ecdh_helper.c (2016B)
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) + 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, ¶ms->key_size, sizeof(params->key_size)); 50 ecdh_pack_data(ptr, params->key, params->key_size); 51 52 return 0; 53} 54EXPORT_SYMBOL_GPL(crypto_ecdh_encode_key); 55 56int crypto_ecdh_decode_key(const char *buf, unsigned int len, 57 struct ecdh *params) 58{ 59 const u8 *ptr = buf; 60 struct kpp_secret secret; 61 62 if (unlikely(!buf || len < ECDH_KPP_SECRET_MIN_SIZE)) 63 return -EINVAL; 64 65 ptr = ecdh_unpack_data(&secret, ptr, sizeof(secret)); 66 if (secret.type != CRYPTO_KPP_SECRET_TYPE_ECDH) 67 return -EINVAL; 68 69 if (unlikely(len < secret.len)) 70 return -EINVAL; 71 72 ptr = ecdh_unpack_data(¶ms->key_size, ptr, sizeof(params->key_size)); 73 if (secret.len != crypto_ecdh_key_len(params)) 74 return -EINVAL; 75 76 /* Don't allocate memory. Set pointer to data 77 * within the given buffer 78 */ 79 params->key = (void *)ptr; 80 81 return 0; 82} 83EXPORT_SYMBOL_GPL(crypto_ecdh_decode_key);