Embedded SDK
Embedded SDK
cx_selftests.c
Go to the documentation of this file.
1 
2 /*******************************************************************************
3  * Ledger Nano S - Secure firmware
4  * (c) 2022 Ledger
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ********************************************************************************/
18 
19 #ifdef HAVE_SELFTESTS
20 
21 #include "os.h"
22 #include "cx_selftests.h"
23 #include "cx_ecfp.h"
24 #include "cx_eddsa.h"
25 #include "cx_ram.h"
26 
27 enum test_id {
28  CX_TEST_MATHM_ID,
29 
30  CX_TEST_AES_ID,
31 
32  CX_TEST_RIPEMD160_ID,
33  CX_TEST_SHA224_ID,
34  CX_TEST_SHA256_ID,
35  CX_TEST_SHA384_ID,
36  CX_TEST_SHA512_ID,
37 
38  CX_TEST_SHA3_ID,
39  CX_TEST_SHA3_XOF_ID,
40 
41  CX_TEST_BLAKE2B_ID,
42  CX_TEST_GROESTL_ID,
43 
44  CX_TEST_HMAC_RIPEMD160_ID,
45  CX_TEST_HMAC_SHA256_ID,
46  CX_TEST_HMAC_SHA512_ID,
47  CX_TEST_PBKDF2_ID,
48 
49  CX_TEST_ECDSA_ID,
50  CX_TEST_ECDSA_RFC6979_ID,
51 
52  CX_TEST_EDDSA_ID,
53 
54  CX_TEST_ECSCHNORR_ID,
55 
56  CX_TEST_BORROMEAN_ID,
57 
58  CX_TEST_ECFP_ADD_ID,
59 
60  CX_TEST_EC_KEYGEN_ID,
61 
62  CX_TEST_ECDH_ID,
63 
64  CX_TEST_RSA_ID,
65 
66  // how many
67  CX_TEST_COUNT,
68 };
69 
70 typedef struct cx_selftest_s {
71  uint8_t _in[512];
72  uint8_t _out[512];
73  int _cx_failure_counter;
74  int _cx_results[CX_TEST_COUNT];
75 } cx_selftest_t;
76 
77 #define G_HAVE_SELFTESTS ((cx_selftest_t *) 0x0020000800)
78 #define IN G_HAVE_SELFTESTS->_in
79 #define OUT G_HAVE_SELFTESTS->_out
80 #define cx_failure_counter G_HAVE_SELFTESTS->_cx_failure_counter
81 #define cx_results G_HAVE_SELFTESTS->_cx_results
82 
83 void cx_bm_setup();
84 void cx_bm_start();
85 void cx_bm_stop();
86 
87 void cx_printa(char *prefix, const unsigned char *r, unsigned short len)
88 {
89  UNUSED(prefix);
90  cx_printf((" %s %.4d ", prefix, len));
91  while (len--) {
92  cx_printf(("%.2x", *r));
93  r++;
94  }
95  cx_printf(("\n"));
96 }
97 
98 #ifdef ST31
99 #include "product.h"
100 #endif
101 
102 int cx_st_onefail(void)
103 {
104  volatile int i = 1; // avoid inline
105  // breaker
106  return i;
107 }
108 
109 int cx_break(void)
110 {
111  volatile int i = 2; // avoid inline
112  // breaker
113  return i;
114 }
115 
116 void cx_st_check_result(int r, int ID, int c)
117 {
118  if (r) {
119  cx_results[ID] |= 1 << c;
120  cx_failure_counter++;
121  cx_st_onefail();
122  }
123 }
124 /* ======================================================================= */
125 /* RAM BUFF */
126 /* ======================================================================= */
127 
128 static void cx_clr_inout(void)
129 {
130  memset(IN, 0, sizeof(IN));
131  memset(OUT, 0, sizeof(OUT));
132 }
133 
134 /* ======================================================================= */
135 /* RAND */
136 /* ======================================================================= */
137 
138 /*
139 *************************************** 1 skip 0
140 *********************************************************
141 --------REF--------
142 order fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
143 secexp c48b5c4c5b2ae33df94192f6269d55921fb0f095be4d843b507a2a716954eea7
144 hash b'ef84dae8cb46951314920500ec18a38670cda437b45c7aeaa73662166638f74d'
145 ref b2i/ x= ef84dae8cb46951314920500ec18a38670cda437b45c7aeaa73662166638f74d (256)
146 ref b2i/ ret ef84dae8cb46951314920500ec18a38670cda437b45c7aeaa73662166638f74d
147 qlen 256
148 holen 32
149 rolen 32
150 ref B/ V= b'0101010101010101010101010101010101010101010101010101010101010101'
151 ref C/ V= b'0000000000000000000000000000000000000000000000000000000000000000'
152 ref D/ i= b'010101010101010101010101010101010101010101010101010101010101010100'
153 ref D/ i= b'c48b5c4c5b2ae33df94192f6269d55921fb0f095be4d843b507a2a716954eea7'
154 ref D/ i= b'ef84dae8cb46951314920500ec18a38670cda437b45c7aeaa73662166638f74d'
155 ref D/ i= b''
156 ref D/ K= b'c446324ebec5416899f23fdd3d89432575ec0e16f901b1b0e074c15dffcb3676'
157 ref E/ V= b'122feea4ac17a41e01b31608cf2d8899f1518e7601b375eeaf7fddeb2525b7ec'
158 ref F/ V= b'7bf9d593c9514dbf18a86cd26cfcc39cf87dafd993dfb00b129c723eb3cba4a1'
159 ref G/ V= b'2fb05f6bf880fb602918990e503a75367e5078fd928b5a608ebf77fc0f5d6a9e'
160 ref H3/ loop 0: 0 < 32 :: True
161 ref H3/ T= 32 ?< 32 b'b22ac3d26ff3734315f18c9662e7c7d8e84a1e83a6d9c77766e6e149a53c584f'
162 ref b2i/ x= b22ac3d26ff3734315f18c9662e7c7d8e84a1e83a6d9c77766e6e149a53c584f (256)
163 ref b2i/ ret b22ac3d26ff3734315f18c9662e7c7d8e84a1e83a6d9c77766e6e149a53c584f
164 
165 => b22ac3d26ff3734315f18c9662e7c7d8e84a1e83a6d9c77766e6e149a53c584f
166 */
167 static const unsigned char rfc6979_sha256_order1[] = {
168  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
169  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x2f};
170 static const unsigned char rfc6979_sha256_key1[] = {
171  0xc4, 0x8b, 0x5c, 0x4c, 0x5b, 0x2a, 0xe3, 0x3d, 0xf9, 0x41, 0x92, 0xf6, 0x26, 0x9d, 0x55, 0x92,
172  0x1f, 0xb0, 0xf0, 0x95, 0xbe, 0x4d, 0x84, 0x3b, 0x50, 0x7a, 0x2a, 0x71, 0x69, 0x54, 0xee, 0xa7};
173 static const unsigned char rfc6979_sha256_hash1[] = {
174  0xef, 0x84, 0xda, 0xe8, 0xcb, 0x46, 0x95, 0x13, 0x14, 0x92, 0x05, 0x00, 0xec, 0x18, 0xa3, 0x86,
175  0x70, 0xcd, 0xa4, 0x37, 0xb4, 0x5c, 0x7a, 0xea, 0xa7, 0x36, 0x62, 0x16, 0x66, 0x38, 0xf7, 0x4d};
176 /*
177 
178 *************************************** 2 skip 0
179 *********************************************************
180 --------REF--------
181 order 0800000000000011000000000000000000000000000000000000000000000001
182 secexp 3f8311eece8cafea3bf568aa90457ad6bbc47deed0e3c44e0aa94b98ac41f
183 hash b'e511c5432ea4f80aa434b842fe5398ec23d62f3e0da06c2400005ef9c7ac1b4b'
184 ref b2i/ x= e511c5432ea4f80aa434b842fe5398ec23d62f3e0da06c2400005ef9c7ac1b4b (256)
185 ref b2i/ shift by 4
186 qlen 252
187 holen 32
188 rolen 32
189 ref B/ V= b'0101010101010101010101010101010101010101010101010101010101010101'
190 ref C/ V= b'0000000000000000000000000000000000000000000000000000000000000000'
191 ref D/ i= b'010101010101010101010101010101010101010101010101010101010101010100'
192 ref D/ i= b'0003f8311eece8cafea3bf568aa90457ad6bbc47deed0e3c44e0aa94b98ac41f'
193 ref D/ i= b'06511c5432ea4f6faa434b842fe5398ec23d62f3e0da06c2400005ef9c7ac1b3'
194 ref D/ i= b''
195 ref D/ K= b'387e7380b6499950fef0661cee7e11346f3ed21ff34331847832d5669e227fa0'
196 ref E/ V= b'ee6cadf713e3211a719f64180851b873773075e7259839a110ce527871f4b801'
197 ref F/ V= b'c735259ef043020c7f9c1633d10643444979ee5ee67ff836593f9a99c87006a9'
198 ref G/ V= b'f4c60173490d35c3341954bd9b07d430da2fb0c70cb578d0b98059d11fa2fa37'
199 ref H3/ loop 0: 0 < 32 :: True
200 ref H3/ T= 32 ?< 32 b'de22c0b3708147a2301738a26af35e08ba4512e49abda4b88c2e4aa889226200'
201 ref b2i/ x= de22c0b3708147a2301738a26af35e08ba4512e49abda4b88c2e4aa889226200 (256)
202 ref b2i/ shift by 4
203 ref H3/ skip bad de22c0b3708147a2301738a26af35e08ba4512e49abda4b88c2e4aa88922620
204 ref H3/ loop 0: 0 < 32 :: True
205 ref H3/ T= 32 ?< 32 b'0b8c9f65f6a2a026f75b621380bb23089362c71c6212b3cceaa6c99d2e414d8c'
206 ref b2i/ x= b8c9f65f6a2a026f75b621380bb23089362c71c6212b3cceaa6c99d2e414d8c (256)
207 ref b2i/ shift by 4
208 
209 => b8c9f65f6a2a026f75b621380bb23089362c71c6212b3cceaa6c99d2e414d8
210 */
211 
212 static const unsigned char rfc6979_sha256_order2[] = {
213  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
215 static const unsigned char rfc6979_sha256_key2[] = {
216  0x00, 0x03, 0xf8, 0x31, 0x1e, 0xec, 0xe8, 0xca, 0xfe, 0xa3, 0xbf, 0x56, 0x8a, 0xa9, 0x04, 0x57,
217  0xad, 0x6b, 0xbc, 0x47, 0xde, 0xed, 0x0e, 0x3c, 0x44, 0xe0, 0xaa, 0x94, 0xb9, 0x8a, 0xc4, 0x1f};
218 static const unsigned char rfc6979_sha256_hash2[] = {
219  0xe5, 0x11, 0xc5, 0x43, 0x2e, 0xa4, 0xf8, 0x0a, 0xa4, 0x34, 0xb8, 0x42, 0xfe, 0x53, 0x98, 0xec,
220  0x23, 0xd6, 0x2f, 0x3e, 0x0d, 0xa0, 0x6c, 0x24, 0x00, 0x00, 0x5e, 0xf9, 0xc7, 0xac, 0x1b, 0x4b};
221 
222 void cx_st_rfc6979()
223 {
224  cx_rng_rfc6979(CX_SHA256,
225  rfc6979_sha256_key1,
226  sizeof(rfc6979_sha256_key1),
227  rfc6979_sha256_hash1,
228  sizeof(rfc6979_sha256_hash1),
229  rfc6979_sha256_order1,
230  sizeof(rfc6979_sha256_order1),
231  OUT,
232  sizeof(rfc6979_sha256_order1));
233 
234  cx_rng_rfc6979(CX_SHA256,
235  rfc6979_sha256_key2,
236  sizeof(rfc6979_sha256_key2),
237  rfc6979_sha256_hash2,
238  sizeof(rfc6979_sha256_hash2),
239  rfc6979_sha256_order2,
240  sizeof(rfc6979_sha256_order2),
241  OUT,
242  sizeof(rfc6979_sha256_order1));
243 }
244 
245 // =====================================================================================
246 
247 int cx_selftest()
248 {
249  int volatile looper = HAVE_SELFTESTS_START_LOOP;
250  while (looper)
251  ;
252  memset(G_HAVE_SELFTESTS, 0, sizeof(cx_selftest_t));
253  cx_st_rfc6979();
254 
255  cx_break();
256  return cx_failure_counter;
257 }
258 
259 #endif // SELFTEST
void cx_printa(char *prefix, const unsigned char *r, unsigned short len)
#define cx_printf(a)
Definition: cx_selftests.h:29
#define HAVE_SELFTESTS_START_LOOP
Definition: cx_selftests.h:23
unsigned char uint8_t
Definition: usbd_conf.h:53