2 * Copyright (c) 2016, Intel Corporation
3 * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
10 #include <linux/kernel.h>
11 #include <linux/export.h>
12 #include <linux/err.h>
13 #include <linux/string.h>
14 #include <crypto/dh.h>
15 #include <crypto/kpp.h>
17 #define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int))
19 static inline u8
*dh_pack_data(void *dst
, const void *src
, size_t size
)
21 memcpy(dst
, src
, size
);
25 static inline const u8
*dh_unpack_data(void *dst
, const void *src
, size_t size
)
27 memcpy(dst
, src
, size
);
31 static inline int dh_data_size(const struct dh
*p
)
33 return p
->key_size
+ p
->p_size
+ p
->g_size
;
36 int crypto_dh_key_len(const struct dh
*p
)
38 return DH_KPP_SECRET_MIN_SIZE
+ dh_data_size(p
);
40 EXPORT_SYMBOL_GPL(crypto_dh_key_len
);
42 int crypto_dh_encode_key(char *buf
, unsigned int len
, const struct dh
*params
)
45 struct kpp_secret secret
= {
46 .type
= CRYPTO_KPP_SECRET_TYPE_DH
,
53 if (len
!= crypto_dh_key_len(params
))
56 ptr
= dh_pack_data(ptr
, &secret
, sizeof(secret
));
57 ptr
= dh_pack_data(ptr
, ¶ms
->key_size
, sizeof(params
->key_size
));
58 ptr
= dh_pack_data(ptr
, ¶ms
->p_size
, sizeof(params
->p_size
));
59 ptr
= dh_pack_data(ptr
, ¶ms
->g_size
, sizeof(params
->g_size
));
60 ptr
= dh_pack_data(ptr
, params
->key
, params
->key_size
);
61 ptr
= dh_pack_data(ptr
, params
->p
, params
->p_size
);
62 dh_pack_data(ptr
, params
->g
, params
->g_size
);
66 EXPORT_SYMBOL_GPL(crypto_dh_encode_key
);
68 int crypto_dh_decode_key(const char *buf
, unsigned int len
, struct dh
*params
)
71 struct kpp_secret secret
;
73 if (unlikely(!buf
|| len
< DH_KPP_SECRET_MIN_SIZE
))
76 ptr
= dh_unpack_data(&secret
, ptr
, sizeof(secret
));
77 if (secret
.type
!= CRYPTO_KPP_SECRET_TYPE_DH
)
80 ptr
= dh_unpack_data(¶ms
->key_size
, ptr
, sizeof(params
->key_size
));
81 ptr
= dh_unpack_data(¶ms
->p_size
, ptr
, sizeof(params
->p_size
));
82 ptr
= dh_unpack_data(¶ms
->g_size
, ptr
, sizeof(params
->g_size
));
83 if (secret
.len
!= crypto_dh_key_len(params
))
86 /* Don't allocate memory. Set pointers to data within
89 params
->key
= (void *)ptr
;
90 params
->p
= (void *)(ptr
+ params
->key_size
);
91 params
->g
= (void *)(ptr
+ params
->key_size
+ params
->p_size
);
95 EXPORT_SYMBOL_GPL(crypto_dh_decode_key
);