1 /* kcapi_dh.c
2 *
3 * Copyright (C) 2006-2020 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/wolfcrypt/settings.h>
28
29 #if defined(WOLFSSL_KCAPI_DH)
30
31 #include <wolfssl/wolfcrypt/error-crypt.h>
32 #include <wolfssl/wolfcrypt/logging.h>
33 #include <wolfssl/wolfcrypt/port/kcapi/wc_kcapi.h>
34 #include <wolfssl/wolfcrypt/port/kcapi/kcapi_dh.h>
35 #include <wolfssl/wolfcrypt/dh.h>
36 #include <wolfssl/wolfcrypt/asn.h>
37
38 static const char WC_NAME_DH[] = "dh";
39
KcapiDh_Free(DhKey * key)40 void KcapiDh_Free(DhKey* key)
41 {
42 if (key->handle != NULL) {
43 kcapi_kpp_destroy(key->handle);
44 key->handle = NULL;
45 }
46 }
47
KcapiDh_SetParams(DhKey * key)48 static int KcapiDh_SetParams(DhKey* key)
49 {
50 #if defined(HAVE_FIPS) && \
51 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
52 int ret = 0;
53 unsigned char* pkcs3 = NULL;
54 word32 len = 0, idx = 0, len2;
55
56 len = MAX_SEQ_SZ; /* Sequence */
57 len += ASN_TAG_SZ + MAX_LENGTH_SZ; /* Integer */
58 len += mp_leading_bit(&key->p) ? 1 : 0;
59 len += mp_unsigned_bin_size(&key->p);
60 len += ASN_TAG_SZ + MAX_LENGTH_SZ; /* Integer */
61 len += mp_leading_bit(&key->g) ? 1 : 0;
62 len += mp_unsigned_bin_size(&key->g);
63
64 pkcs3 = (unsigned char*)XMALLOC(len, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
65 if (pkcs3 == NULL) {
66 ret = MEMORY_E;
67 }
68
69 if (ret == 0) {
70 idx = len;
71 len2 = mp_unsigned_bin_size(&key->g);
72 idx -= len2;
73 ret = mp_to_unsigned_bin(&key->g, pkcs3 + idx);
74 }
75 if (ret >= 0) {
76 if (mp_leading_bit(&key->g)) {
77 pkcs3[--idx] = 0x00;
78 len2++;
79 }
80 idx -= SetLength(len2, NULL);
81 SetLength(len2, pkcs3 + idx);
82 pkcs3[--idx] = ASN_INTEGER;
83
84 len2 = mp_unsigned_bin_size(&key->p);
85 idx -= len2;
86 ret = mp_to_unsigned_bin(&key->p, pkcs3 + idx);
87 }
88 if (ret >= 0) {
89 if (mp_leading_bit(&key->p)) {
90 pkcs3[--idx] = 0x00;
91 len2++;
92 }
93 idx -= SetLength(len2, NULL);
94 SetLength(len2, pkcs3 + idx);
95 pkcs3[--idx] = ASN_INTEGER;
96
97 len2 = len - idx;
98 idx -= SetSequence(len2, NULL);
99 SetSequence(len2, pkcs3 + idx);
100
101 ret = kcapi_kpp_dh_setparam_pkcs3(key->handle, pkcs3 + idx, len - idx);
102 if (ret != 0) {
103 WOLFSSL_MSG("KcapiDh_SetParams: Failed to set");
104 }
105 }
106
107 if (pkcs3 != NULL) {
108 XFREE(pkcs3, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
109 }
110 return ret;
111 #else
112 int ret;
113 unsigned char* pkcs3 = NULL;
114 word32 len;
115
116 ret = wc_DhParamsToDer(key, NULL, &len);
117 if (ret == LENGTH_ONLY_E) {
118 ret = 0;
119 pkcs3 = (unsigned char*)XMALLOC(len, key->heap,
120 DYNAMIC_TYPE_TMP_BUFFER);
121 if (pkcs3 == NULL) {
122 ret = MEMORY_E;
123 }
124 }
125 if (ret == 0) {
126 ret = wc_DhParamsToDer(key, pkcs3, &len);
127 }
128 if (ret == 0) {
129 ret = kcapi_kpp_dh_setparam_pkcs3(key->handle, pkcs3, len);
130 if (ret != 0) {
131 WOLFSSL_MSG("KcapiDh_SetParams: Failed to set");
132 }
133 }
134
135 if (pkcs3 != NULL) {
136 XFREE(pkcs3, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
137 }
138 return ret;
139 #endif
140 }
141
KcapiDh_MakeKey(DhKey * key,byte * pub,word32 * pubSz)142 int KcapiDh_MakeKey(DhKey* key, byte* pub, word32* pubSz)
143 {
144 int ret = 0;
145
146 if (key->handle != NULL) {
147 kcapi_kpp_destroy(key->handle);
148 key->handle = NULL;
149 }
150 if (ret == 0) {
151 ret = kcapi_kpp_init(&key->handle, WC_NAME_DH, 0);
152 if (ret != 0) {
153 WOLFSSL_MSG("KcapiDh_MakeKey: Failed to initialization");
154 }
155 }
156
157 if (ret == 0) {
158 ret = KcapiDh_SetParams(key);
159 }
160 if (ret == 0) {
161 ret = kcapi_kpp_keygen(key->handle, pub, *pubSz,
162 KCAPI_ACCESS_HEURISTIC);
163 }
164
165 return ret;
166 }
167
KcapiDh_SharedSecret(DhKey * private_key,const byte * pub,word32 pubSz,byte * out,word32 * outlen)168 int KcapiDh_SharedSecret(DhKey* private_key, const byte* pub, word32 pubSz,
169 byte* out, word32* outlen)
170 {
171 int ret;
172
173 ret = kcapi_kpp_ssgen(private_key->handle, pub, pubSz, out, *outlen,
174 KCAPI_ACCESS_HEURISTIC);
175 if (ret >= 0) {
176 *outlen = ret;
177 ret = 0;
178 }
179
180 return ret;
181 }
182
183 #endif /* WOLFSSL_KCAPI_DH */
184