~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/crypto/dh_helper.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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/dh.h>
 11 #include <crypto/kpp.h>
 12 
 13 #define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int))
 14 
 15 static inline u8 *dh_pack_data(u8 *dst, u8 *end, const void *src, size_t size)
 16 {
 17         if (!dst || size > end - dst)
 18                 return NULL;
 19         memcpy(dst, src, size);
 20         return dst + size;
 21 }
 22 
 23 static inline const u8 *dh_unpack_data(void *dst, const void *src, size_t size)
 24 {
 25         memcpy(dst, src, size);
 26         return src + size;
 27 }
 28 
 29 static inline unsigned int dh_data_size(const struct dh *p)
 30 {
 31         return p->key_size + p->p_size + p->g_size;
 32 }
 33 
 34 unsigned int crypto_dh_key_len(const struct dh *p)
 35 {
 36         return DH_KPP_SECRET_MIN_SIZE + dh_data_size(p);
 37 }
 38 EXPORT_SYMBOL_GPL(crypto_dh_key_len);
 39 
 40 int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
 41 {
 42         u8 *ptr = buf;
 43         u8 * const end = ptr + len;
 44         struct kpp_secret secret = {
 45                 .type = CRYPTO_KPP_SECRET_TYPE_DH,
 46                 .len = len
 47         };
 48 
 49         if (unlikely(!len))
 50                 return -EINVAL;
 51 
 52         ptr = dh_pack_data(ptr, end, &secret, sizeof(secret));
 53         ptr = dh_pack_data(ptr, end, &params->key_size,
 54                            sizeof(params->key_size));
 55         ptr = dh_pack_data(ptr, end, &params->p_size, sizeof(params->p_size));
 56         ptr = dh_pack_data(ptr, end, &params->g_size, sizeof(params->g_size));
 57         ptr = dh_pack_data(ptr, end, params->key, params->key_size);
 58         ptr = dh_pack_data(ptr, end, params->p, params->p_size);
 59         ptr = dh_pack_data(ptr, end, params->g, params->g_size);
 60         if (ptr != end)
 61                 return -EINVAL;
 62         return 0;
 63 }
 64 EXPORT_SYMBOL_GPL(crypto_dh_encode_key);
 65 
 66 int __crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
 67 {
 68         const u8 *ptr = buf;
 69         struct kpp_secret secret;
 70 
 71         if (unlikely(!buf || len < DH_KPP_SECRET_MIN_SIZE))
 72                 return -EINVAL;
 73 
 74         ptr = dh_unpack_data(&secret, ptr, sizeof(secret));
 75         if (secret.type != CRYPTO_KPP_SECRET_TYPE_DH)
 76                 return -EINVAL;
 77 
 78         ptr = dh_unpack_data(&params->key_size, ptr, sizeof(params->key_size));
 79         ptr = dh_unpack_data(&params->p_size, ptr, sizeof(params->p_size));
 80         ptr = dh_unpack_data(&params->g_size, ptr, sizeof(params->g_size));
 81         if (secret.len != crypto_dh_key_len(params))
 82                 return -EINVAL;
 83 
 84         /* Don't allocate memory. Set pointers to data within
 85          * the given buffer
 86          */
 87         params->key = (void *)ptr;
 88         params->p = (void *)(ptr + params->key_size);
 89         params->g = (void *)(ptr + params->key_size + params->p_size);
 90 
 91         return 0;
 92 }
 93 
 94 int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
 95 {
 96         int err;
 97 
 98         err = __crypto_dh_decode_key(buf, len, params);
 99         if (err)
100                 return err;
101 
102         /*
103          * Don't permit the buffer for 'key' or 'g' to be larger than 'p', since
104          * some drivers assume otherwise.
105          */
106         if (params->key_size > params->p_size ||
107             params->g_size > params->p_size)
108                 return -EINVAL;
109 
110         /*
111          * Don't permit 'p' to be 0.  It's not a prime number, and it's subject
112          * to corner cases such as 'mod 0' being undefined or
113          * crypto_kpp_maxsize() returning 0.
114          */
115         if (memchr_inv(params->p, 0, params->p_size) == NULL)
116                 return -EINVAL;
117 
118         return 0;
119 }
120 EXPORT_SYMBOL_GPL(crypto_dh_decode_key);
121 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php