1 /*
2 * Copyright (c) 2021-2023, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== ECCParamsLPF3SW.c ========
34 *
35 * This file contains structure definitions for various ECC curves for use
36 * on L devices.
37 */
38
39 #include <stdbool.h>
40 #include <stdint.h>
41 #include <string.h>
42
43 #include <ti/drivers/cryptoutils/ecc/ECCParams.h>
44 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
45
46 /*
47 * Curve parameters are formatted as little-endian integers with a prepended
48 * length word in words as required by the ECC SW library.
49 */
50
51 /*
52 * NIST P256 curve params in little endian format.
53 * byte[0-3] are the param length word as required by the ECC SW library.
54 * byte[4] is the least significant byte of the curve parameter.
55 */
56 const ECC_NISTP256_Param ECC_NISTP256_generatorX = {
57 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
58 0x96, 0xc2, 0x98, 0xd8, 0x45, 0x39, 0xa1, 0xf4, 0xa0, 0x33, 0xeb, 0x2d, 0x81, 0x7d, 0x03, 0x77,
59 0xf2, 0x40, 0xa4, 0x63, 0xe5, 0xe6, 0xbc, 0xf8, 0x47, 0x42, 0x2c, 0xe1, 0xf2, 0xd1, 0x17, 0x6b}};
60
61 const ECC_NISTP256_Param ECC_NISTP256_generatorY = {
62 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
63 0xf5, 0x51, 0xbf, 0x37, 0x68, 0x40, 0xb6, 0xcb, 0xce, 0x5e, 0x31, 0x6b, 0x57, 0x33, 0xce, 0x2b,
64 0x16, 0x9e, 0x0f, 0x7c, 0x4a, 0xeb, 0xe7, 0x8e, 0x9b, 0x7f, 0x1a, 0xfe, 0xe2, 0x42, 0xe3, 0x4f}};
65
66 const ECC_NISTP256_Param ECC_NISTP256_prime = {
67 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
68 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}};
70
71 const ECC_NISTP256_Param ECC_NISTP256_a = {.byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
72 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
73 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}};
75
76 const ECC_NISTP256_Param ECC_NISTP256_b = {.byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
77 0x4b, 0x60, 0xd2, 0x27, 0x3e, 0x3c, 0xce, 0x3b, 0xf6, 0xb0, 0x53,
78 0xcc, 0xb0, 0x06, 0x1d, 0x65, 0xbc, 0x86, 0x98, 0x76, 0x55, 0xbd,
79 0xeb, 0xb3, 0xe7, 0x93, 0x3a, 0xaa, 0xd8, 0x35, 0xc6, 0x5a}};
80
81 const ECC_NISTP256_Param ECC_NISTP256_order = {
82 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
83 0x51, 0x25, 0x63, 0xfc, 0xc2, 0xca, 0xb9, 0xf3, 0x84, 0x9e, 0x17, 0xa7, 0xad, 0xfa, 0xe6, 0xbc,
84 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}};
85
86 /*
87 * Curve params in Montgomery domain are used for public key validation only
88 * and are not prefixed with a length word.
89 */
90 /* Invert of square of Montgomery constant, k = 2^(256) mod p, p is the curve prime */
91 const ECC_NISTP256_Param ECC_NISTP256_k_mont = {
92 .byte = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff,
93 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00}};
94
95 /* Converted to Montgomery domain by modular multiplication of ECC_NISTP256_a with ECC_NISTP224_k_mont */
96 const ECC_NISTP256_Param ECC_NISTP256_a_mont = {
97 .byte = {0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff}};
99
100 /* Converted to Montgomery domain by modular multiplication of ECC_NISTP256_b with ECC_NISTP224_k_mont */
101 const ECC_NISTP256_Param ECC_NISTP256_b_mont = {
102 .byte = {0xdf, 0xbd, 0xc4, 0x29, 0x62, 0xdf, 0x9c, 0xd8, 0x90, 0x30, 0x84, 0x78, 0xcd, 0x05, 0xf0, 0xac,
103 0xd6, 0x2e, 0x21, 0xf7, 0xab, 0x20, 0xa2, 0xe5, 0x34, 0x48, 0x87, 0x04, 0x1d, 0x06, 0x30, 0xdc}};
104
105 const ECCParams_CurveParams ECCParams_NISTP256 = {.curveType = ECCParams_CURVE_TYPE_SHORT_WEIERSTRASS_AN3,
106 .length = ECCParams_NISTP256_LENGTH,
107 .prime = ECC_NISTP256_prime.byte,
108 .order = ECC_NISTP256_order.byte,
109 .a = ECC_NISTP256_a.byte,
110 .b = ECC_NISTP256_b.byte,
111 .generatorX = ECC_NISTP256_generatorX.byte,
112 .generatorY = ECC_NISTP256_generatorY.byte,
113 .cofactor = 1};
114
115 /*
116 * NIST P224 curve params in little endian format.
117 * byte[0-3] are the param length word as required by the ECC SW library.
118 * byte[4] is the least significant byte of the curve parameter.
119 */
120 const ECC_NISTP224_Param ECC_NISTP224_generatorX = {.byte = {0x07, 0x00, 0x00, 0x00, /* Length word prefix */
121 0x21, 0x1d, 0x5c, 0x11, 0xd6, 0x80, 0x32, 0x34, 0x22, 0x11,
122 0xc2, 0x56, 0xd3, 0xc1, 0x03, 0x4a, 0xb9, 0x90, 0x13, 0x32,
123 0x7f, 0xbf, 0xb4, 0x6b, 0xbd, 0x0c, 0x0e, 0xb7}};
124
125 const ECC_NISTP224_Param ECC_NISTP224_generatorY = {.byte = {
126 0x07, 0x00, 0x00, 0x00, /* Length word prefix */
127 0x34, 0x7e, 0x00, 0x85, 0x99, 0x81, 0xd5, 0x44, 0x64, 0x47,
128 0x07, 0x5a, 0xa0, 0x75, 0x43, 0xcd, 0xe6, 0xdf, 0x22, 0x4c,
129 0xfb, 0x23, 0xf7, 0xb5, 0x88, 0x63, 0x37, 0xbd,
130 }};
131
132 const ECC_NISTP224_Param ECC_NISTP224_prime = {.byte = {0x07, 0x00, 0x00, 0x00, /* Length word prefix */
133 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
135 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
136
137 const ECC_NISTP224_Param ECC_NISTP224_a = {.byte = {0x07, 0x00, 0x00, 0x00, /* Length word prefix */
138 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
139 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
141
142 const ECC_NISTP224_Param ECC_NISTP224_b = {.byte = {0x07, 0x00, 0x00, 0x00, /* Length word prefix */
143 0xb4, 0xff, 0x55, 0x23, 0x43, 0x39, 0x0b, 0x27, 0xba, 0xd8,
144 0xbf, 0xd7, 0xb7, 0xb0, 0x44, 0x50, 0x56, 0x32, 0x41, 0xf5,
145 0xab, 0xb3, 0x04, 0x0c, 0x85, 0x0a, 0x05, 0xb4}};
146
147 const ECC_NISTP224_Param ECC_NISTP224_order = {.byte = {0x07, 0x00, 0x00, 0x00, /* Length word prefix */
148 0x3d, 0x2a, 0x5c, 0x5c, 0x45, 0x29, 0xdd, 0x13, 0x3e, 0xf0,
149 0xb8, 0xe0, 0xa2, 0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
150 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
151
152 /*
153 * Curve params in Montgomery domain are used for public key validation only
154 * and are not prefixed with a length word.
155 */
156 /* Invert of square of Montgomery constant, k = 2^(224) mod p, p is the curve prime */
157 const ECC_NISTP224_Param ECC_NISTP224_k_mont = {.byte = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
159 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}};
160
161 /* Converted to Montgomery domain by modular multiplication of ECC_NISTP224_a with ECC_NISTP224_k_mont */
162 const ECC_NISTP224_Param ECC_NISTP224_a_mont = {.byte = {0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
164 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
165
166 /* Converted to Montgomery domain by modular multiplication of ECC_NISTP224_b with ECC_NISTP224_k_mont */
167 const ECC_NISTP224_Param ECC_NISTP224_b_mont = {.byte = {0xF7, 0xCD, 0x68, 0xE7, 0x10, 0x13, 0xF0, 0xCC, 0xC0, 0x1C,
168 0x3B, 0x74, 0x50, 0x81, 0x52, 0xC8, 0x98, 0xBA, 0xCE, 0x3D,
169 0x93, 0x2F, 0xC0, 0x7F, 0x33, 0xA6, 0x3F, 0x9C}};
170
171 const ECCParams_CurveParams ECCParams_NISTP224 = {.curveType = ECCParams_CURVE_TYPE_SHORT_WEIERSTRASS_AN3,
172 .length = ECCParams_NISTP224_LENGTH,
173 .prime = ECC_NISTP224_prime.byte,
174 .order = ECC_NISTP224_order.byte,
175 .a = ECC_NISTP224_a.byte,
176 .b = ECC_NISTP224_b.byte,
177 .generatorX = ECC_NISTP224_generatorX.byte,
178 .generatorY = ECC_NISTP224_generatorY.byte,
179 .cofactor = 1};
180
181 /*
182 * Curve25519 curve params in little endian format.
183 * byte[0-3] are the param length word as required by the ECC SW library.
184 * byte[4] is the least significant byte of the curve parameter.
185 */
186 const ECC_Curve25519_Param ECC_Curve25519_generatorX = {
187 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
188 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
190
191 const ECC_Curve25519_Param ECC_Curve25519_generatorY = {
192 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
193 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, 0x7e, 0x4d, 0x3d, 0x92,
194 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0, 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20}};
195
196 const ECC_Curve25519_Param ECC_Curve25519_prime = {
197 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
198 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}};
200
201 const ECC_Curve25519_Param ECC_Curve25519_a = {
202 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
203 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
205
206 const ECC_Curve25519_Param ECC_Curve25519_b = {
207 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
208 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
210
211 const ECC_Curve25519_Param ECC_Curve25519_order = {
212 .byte = {0x08, 0x00, 0x00, 0x00, /* Length word prefix */
213 0xb9, 0xdc, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
215
216 const ECCParams_CurveParams ECCParams_Curve25519 = {.curveType = ECCParams_CURVE_TYPE_MONTGOMERY,
217 .length = ECCParams_CURVE25519_LENGTH,
218 .prime = ECC_Curve25519_prime.byte,
219 .order = ECC_Curve25519_order.byte,
220 .a = ECC_Curve25519_a.byte,
221 .b = ECC_Curve25519_b.byte,
222 .generatorX = ECC_Curve25519_generatorX.byte,
223 .generatorY = ECC_Curve25519_generatorY.byte,
224 .cofactor = 1};
225
226 /*
227 * ======== ECCParams_formatCurve25519PrivateKey ========
228 */
ECCParams_formatCurve25519PrivateKey(CryptoKey * myPrivateKey)229 int_fast16_t ECCParams_formatCurve25519PrivateKey(CryptoKey *myPrivateKey)
230 {
231 myPrivateKey->u.plaintext.keyMaterial[31] &= 0xF8;
232 myPrivateKey->u.plaintext.keyMaterial[0] &= 0x7F;
233 myPrivateKey->u.plaintext.keyMaterial[0] |= 0x40;
234
235 return ECCParams_STATUS_SUCCESS;
236 }
237
238 /*
239 * ======== ECCParams_getUncompressedGeneratorPoint ========
240 */
ECCParams_getUncompressedGeneratorPoint(const ECCParams_CurveParams * curveParams,uint8_t * buffer,size_t length)241 int_fast16_t ECCParams_getUncompressedGeneratorPoint(const ECCParams_CurveParams *curveParams,
242 uint8_t *buffer,
243 size_t length)
244 {
245
246 size_t paramLength = curveParams->length;
247 size_t pointLength = (paramLength * 2) + 1;
248
249 if (length < pointLength)
250 {
251 return ECCParams_STATUS_ERROR;
252 }
253
254 /* Reverse and concatenate x and y */
255 uint32_t i = 0;
256 for (i = 0; i < paramLength; i++)
257 {
258 buffer[i + 1] = curveParams->generatorX[paramLength + ECC_LENGTH_PREFIX_BYTES - i - 1];
259 buffer[i + 1 + paramLength] = curveParams->generatorY[paramLength + ECC_LENGTH_PREFIX_BYTES - i - 1];
260 }
261
262 buffer[0] = 0x04;
263 /* Fill the remaining buffer with 0 if needed */
264 memset(buffer + pointLength, 0, length - pointLength);
265
266 return ECCParams_STATUS_SUCCESS;
267 }
268