1 /* psoc6_crypto.c
2 *
3 * Copyright (C) 2006-2021 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 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <wolfssl/wolfcrypt/settings.h>
27 #ifdef NO_INLINE
28 #include <wolfssl/wolfcrypt/misc.h>
29 #else
30 #define WOLFSSL_MISC_INCLUDED
31 #include <wolfcrypt/src/misc.c>
32 #endif
33
34 #if defined(WOLFSSL_PSOC6_CRYPTO)
35 #ifdef WOLFSSL_SP_MATH
36 struct sp_int;
37 #define MATH_INT_T struct sp_int
38 #elif defined(USE_FAST_MATH)
39 struct fp_int;
40 #define MATH_INT_T struct fp_int
41 #else
42 struct mp_int;
43 #define MATH_INT_T struct mp_int
44 #endif
45
46 #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
47 #include <wolfssl/wolfcrypt/random.h>
48 #include <wolfssl/wolfcrypt/error-crypt.h>
49 #include <wolfssl/wolfcrypt/logging.h>
50 #include <stdint.h>
51
52 static CRYPTO_Type *crypto_base = PSOC6_CRYPTO_BASE;
53
54 /* Hook for device specific initialization */
psoc6_crypto_port_init(void)55 int psoc6_crypto_port_init(void)
56 {
57 Cy_Crypto_Core_Enable(crypto_base);
58 return 0;
59 }
60
61 /* Sha-512 */
62
63 #ifdef WOLFSSL_SHA512
wc_InitSha512(wc_Sha512 * sha)64 int wc_InitSha512(wc_Sha512* sha)
65 {
66 cy_en_crypto_status_t res;
67 if (!sha)
68 return BAD_FUNC_ARG;
69 Cy_Crypto_Core_MemSet(crypto_base, sha, 0, sizeof(sha));
70 res = Cy_Crypto_Core_Sha_Init(crypto_base, &sha->hash_state, CY_CRYPTO_MODE_SHA512, &sha->sha_buffers);
71 if (res != CY_CRYPTO_SUCCESS)
72 return (int)res;
73 return (int) Cy_Crypto_Core_Sha_Start(crypto_base, &sha->hash_state);
74 }
75
wc_Sha512Update(wc_Sha512 * sha,const byte * in,word32 sz)76 int wc_Sha512Update(wc_Sha512* sha, const byte* in, word32 sz)
77 {
78 if ((!sha) || (!in))
79 return BAD_FUNC_ARG;
80 if (sz == 0)
81 return 0;
82
83 return (int)Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
84 }
85
wc_Sha512Final(wc_Sha512 * sha,byte * hash)86 int wc_Sha512Final(wc_Sha512* sha, byte* hash)
87 {
88 if ((!sha) || (!hash))
89 return BAD_FUNC_ARG;
90 return (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
91 }
92
wc_Sha512GetHash(wc_Sha512 * sha,byte * hash)93 int wc_Sha512GetHash(wc_Sha512* sha, byte* hash)
94 {
95 if ((!sha) || (!hash))
96 return BAD_FUNC_ARG;
97 Cy_Crypto_Core_MemCpy(crypto_base, hash, sha->hash_state.hash, WC_SHA512_DIGEST_SIZE);
98 return 0;
99 }
100
wc_Sha512Copy(wc_Sha512 * src,wc_Sha512 * dst)101 int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
102 {
103 cy_en_crypto_status_t res;
104 if ((!dst) || (!src))
105 return BAD_FUNC_ARG;
106 Cy_Crypto_Core_MemCpy(crypto_base, dst, src, sizeof(wc_Sha512));
107 return (int)Cy_Crypto_Core_Sha_Init(crypto_base, &dst->hash_state, CY_CRYPTO_MODE_SHA512, &dst->sha_buffers);
108 }
109
wc_Sha512Free(wc_Sha512 * sha)110 void wc_Sha512Free(wc_Sha512* sha)
111 {
112 if (sha)
113 Cy_Crypto_Core_Sha_Free(crypto_base, &sha->hash_state);
114 }
115
116 #endif
117
118 /* Sha-256 */
119
120 #ifndef NO_SHA256
wc_InitSha256(wc_Sha256 * sha)121 int wc_InitSha256(wc_Sha256* sha)
122 {
123 cy_en_crypto_status_t res;
124 if (!sha)
125 return BAD_FUNC_ARG;
126 Cy_Crypto_Core_MemSet(crypto_base, sha, 0, sizeof(sha));
127 res = Cy_Crypto_Core_Sha_Init(crypto_base, &sha->hash_state, CY_CRYPTO_MODE_SHA256, &sha->sha_buffers);
128 if (res != CY_CRYPTO_SUCCESS)
129 return (int)res;
130 return (int) Cy_Crypto_Core_Sha_Start(crypto_base, &sha->hash_state);
131 }
132
wc_Sha256Update(wc_Sha256 * sha,const byte * in,word32 sz)133 int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz)
134 {
135 if ((!sha) || (!in))
136 return BAD_FUNC_ARG;
137 if (sz == 0)
138 return 0;
139
140 return (int)Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
141 }
142
wc_Sha256Final(wc_Sha256 * sha,byte * hash)143 int wc_Sha256Final(wc_Sha256* sha, byte* hash)
144 {
145 if ((!sha) || (!hash))
146 return BAD_FUNC_ARG;
147 return (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
148 }
149
wc_Sha256GetHash(wc_Sha256 * sha,byte * hash)150 int wc_Sha256GetHash(wc_Sha256* sha, byte* hash)
151 {
152 if ((!sha) || (!hash))
153 return BAD_FUNC_ARG;
154 Cy_Crypto_Core_MemCpy(crypto_base, hash, sha->hash_state.hash, WC_SHA256_DIGEST_SIZE);
155 return 0;
156 }
157
wc_Sha256Copy(wc_Sha256 * src,wc_Sha256 * dst)158 int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
159 {
160 cy_en_crypto_status_t res;
161 if ((!dst) || (!src))
162 return BAD_FUNC_ARG;
163 Cy_Crypto_Core_MemCpy(crypto_base, dst, src, sizeof(wc_Sha256));
164 return (int)Cy_Crypto_Core_Sha_Init(crypto_base, &dst->hash_state, CY_CRYPTO_MODE_SHA256, &dst->sha_buffers);
165 }
166
wc_Sha256Free(wc_Sha256 * sha)167 void wc_Sha256Free(wc_Sha256* sha)
168 {
169 if (sha)
170 Cy_Crypto_Core_Sha_Free(crypto_base, &sha->hash_state);
171 }
172 #endif /* NO_SHA256 */
173
174 /* ECDSA */
175 #ifdef HAVE_ECC
176
177 #define MAX_ECC_KEYSIZE 66 /* Supports up to secp521r1 */
psoc6_get_curve_id(int size)178 static cy_en_crypto_ecc_curve_id_t psoc6_get_curve_id(int size)
179 {
180 switch(size) {
181 case 24:
182 return CY_CRYPTO_ECC_ECP_SECP192R1;
183 case 28:
184 return CY_CRYPTO_ECC_ECP_SECP224R1;
185 case 32:
186 return CY_CRYPTO_ECC_ECP_SECP256R1;
187 case 48:
188 return CY_CRYPTO_ECC_ECP_SECP384R1;
189 case 66:
190 return CY_CRYPTO_ECC_ECP_SECP521R1;
191 default:
192 return CY_CRYPTO_ECC_ECP_NONE;
193 }
194 }
195
196 #include <wolfssl/wolfcrypt/ecc.h>
psoc6_ecc_verify_hash_ex(MATH_INT_T * r,MATH_INT_T * s,const byte * hash,word32 hashlen,int * verif_res,ecc_key * key)197 int psoc6_ecc_verify_hash_ex(MATH_INT_T *r, MATH_INT_T *s, const byte* hash,
198 word32 hashlen, int* verif_res, ecc_key* key)
199 {
200 uint8_t signature_buf[MAX_ECC_KEYSIZE * 2];
201 cy_stc_crypto_ecc_key ecc_key;
202 uint8_t stat = 0;
203 int res = -1;
204 int szModulus;
205 int szkbin;
206 uint8_t x[MAX_ECC_KEYSIZE], y[MAX_ECC_KEYSIZE];
207
208 if (!key || !verif_res || !r || !s || !hash)
209 return -BAD_FUNC_ARG;
210
211 /* retrieve and check sizes */
212 szModulus = mp_unsigned_bin_size(key->pubkey.x);
213 szkbin = mp_unsigned_bin_size(r);
214 if (szModulus > MAX_ECC_KEYSIZE)
215 return -BAD_FUNC_ARG;
216
217 /* Prepare ECC key */
218 ecc_key.type = PK_PUBLIC;
219 ecc_key.curveID = psoc6_get_curve_id(szModulus);
220 ecc_key.k = NULL;
221 ecc_key.pubkey.x = x;
222 ecc_key.pubkey.y = y;
223
224 res = mp_to_unsigned_bin(key->pubkey.x, x);
225 if (res == MP_OKAY)
226 res = mp_to_unsigned_bin(key->pubkey.y, y);
227 Cy_Crypto_Core_InvertEndianness(x, szModulus);
228 Cy_Crypto_Core_InvertEndianness(y, szModulus);
229
230 /* Prepare signature buffer */
231 if (res == MP_OKAY)
232 res = mp_to_unsigned_bin(r, signature_buf);
233 if (res == MP_OKAY)
234 res = mp_to_unsigned_bin(s, signature_buf + szkbin);
235 Cy_Crypto_Core_InvertEndianness(signature_buf, szkbin);
236 Cy_Crypto_Core_InvertEndianness(signature_buf + szkbin, szkbin);
237
238 /* perform HW ECDSA */
239 if (res == MP_OKAY)
240 res = Cy_Crypto_Core_ECC_VerifyHash(crypto_base, signature_buf, hash, hashlen, &stat, &ecc_key);
241 if (res == 0) {
242 *verif_res = stat;
243 }
244 return res;
245 }
246 #endif /* HAVE_ECC */
247
248
249
250 #endif /* defined(WOLFSSL_PSOC6_CRYPTO) */
251
252