at v5.3 2.1 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2016, Intel Corporation 4 * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com> 5 */ 6#include <linux/kernel.h> 7#include <linux/export.h> 8#include <linux/err.h> 9#include <linux/string.h> 10#include <crypto/ecdh.h> 11#include <crypto/kpp.h> 12 13#define ECDH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 2 * sizeof(short)) 14 15static inline u8 *ecdh_pack_data(void *dst, const void *src, size_t sz) 16{ 17 memcpy(dst, src, sz); 18 return dst + sz; 19} 20 21static inline const u8 *ecdh_unpack_data(void *dst, const void *src, size_t sz) 22{ 23 memcpy(dst, src, sz); 24 return src + sz; 25} 26 27unsigned int crypto_ecdh_key_len(const struct ecdh *params) 28{ 29 return ECDH_KPP_SECRET_MIN_SIZE + params->key_size; 30} 31EXPORT_SYMBOL_GPL(crypto_ecdh_key_len); 32 33int crypto_ecdh_encode_key(char *buf, unsigned int len, 34 const struct ecdh *params) 35{ 36 u8 *ptr = buf; 37 struct kpp_secret secret = { 38 .type = CRYPTO_KPP_SECRET_TYPE_ECDH, 39 .len = len 40 }; 41 42 if (unlikely(!buf)) 43 return -EINVAL; 44 45 if (len != crypto_ecdh_key_len(params)) 46 return -EINVAL; 47 48 ptr = ecdh_pack_data(ptr, &secret, sizeof(secret)); 49 ptr = ecdh_pack_data(ptr, &params->curve_id, sizeof(params->curve_id)); 50 ptr = ecdh_pack_data(ptr, &params->key_size, sizeof(params->key_size)); 51 ecdh_pack_data(ptr, params->key, params->key_size); 52 53 return 0; 54} 55EXPORT_SYMBOL_GPL(crypto_ecdh_encode_key); 56 57int crypto_ecdh_decode_key(const char *buf, unsigned int len, 58 struct ecdh *params) 59{ 60 const u8 *ptr = buf; 61 struct kpp_secret secret; 62 63 if (unlikely(!buf || len < ECDH_KPP_SECRET_MIN_SIZE)) 64 return -EINVAL; 65 66 ptr = ecdh_unpack_data(&secret, ptr, sizeof(secret)); 67 if (secret.type != CRYPTO_KPP_SECRET_TYPE_ECDH) 68 return -EINVAL; 69 70 ptr = ecdh_unpack_data(&params->curve_id, ptr, sizeof(params->curve_id)); 71 ptr = ecdh_unpack_data(&params->key_size, ptr, sizeof(params->key_size)); 72 if (secret.len != crypto_ecdh_key_len(params)) 73 return -EINVAL; 74 75 /* Don't allocate memory. Set pointer to data 76 * within the given buffer 77 */ 78 params->key = (void *)ptr; 79 80 return 0; 81} 82EXPORT_SYMBOL_GPL(crypto_ecdh_decode_key);