6 #include "sw/device/lib/base/status.h"
12 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
13 #include "sw/device/lib/ujson/ujson.h"
14 #include "sw/device/tests/crypto/cryptotest/json/ecdh_commands.h"
20 kP256PrivateKeyBytes = 32,
24 kP256MaskedPrivateKeyBytes = 40,
28 kP256MaskedPrivateKeyWords = kP256MaskedPrivateKeyBytes /
sizeof(uint32_t),
32 kP256CoordinateBytes = 32,
36 kP256CoordinateWords = kP256CoordinateBytes /
sizeof(uint32_t),
40 kP256SharedSecretBytes = 32,
44 kP384PrivateKeyBytes = 48,
48 kP384MaskedPrivateKeyBytes = 56,
52 kP384MaskedPrivateKeyWords = kP384MaskedPrivateKeyBytes /
sizeof(uint32_t),
56 kP384CoordinateBytes = 48,
60 kP384CoordinateWords = kP384CoordinateBytes /
sizeof(uint32_t),
64 kP384SharedSecretBytes = 48,
83 static status_t ecdh_p256(cryptotest_ecdh_private_key_t d,
84 cryptotest_ecdh_coordinate_t qx,
85 cryptotest_ecdh_coordinate_t qy, uint32_t *ss,
87 if (d.d0_len > kP256MaskedPrivateKeyBytes ||
88 d.d1_len > kP256MaskedPrivateKeyBytes) {
90 "Bad P-256 private key share length (should both be <= %d): (d0 = %d, "
93 kP256PrivateKeyBytes, d.d0_len, d.d1_len);
94 return INVALID_ARGUMENT();
96 if (qx.coordinate_len > kP256CoordinateBytes ||
97 qy.coordinate_len > kP256CoordinateBytes) {
99 "Bad P-256 coordinate length (should both be <= %d): (x = %d, y = %d)",
100 kP256CoordinateBytes, qx.coordinate_len, qy.coordinate_len);
101 return INVALID_ARGUMENT();
106 uint32_t private_keyblob[kP256MaskedPrivateKeyWords * 2];
107 memset(private_keyblob, 0,
sizeof(private_keyblob));
108 memcpy(private_keyblob, d.d0, d.d0_len);
109 memcpy(private_keyblob + kP256MaskedPrivateKeyWords, d.d1, d.d1_len);
113 .version = kOtcryptoLibVersion1,
114 .key_mode = kOtcryptoKeyModeEcdhP256,
115 .key_length = kP256PrivateKeyBytes,
118 .security_level = kOtcryptoKeySecurityLevelLow,
120 .keyblob_length =
sizeof(private_keyblob),
121 .keyblob = private_keyblob,
127 uint32_t public_key_buf[kP256CoordinateWords * 2];
128 memset(public_key_buf, 0,
sizeof(public_key_buf));
129 memcpy(public_key_buf, qx.coordinate, qx.coordinate_len);
130 memcpy(public_key_buf + kP256CoordinateWords, qy.coordinate,
133 .key_mode = kOtcryptoKeyModeEcdhP256,
134 .key_length =
sizeof(public_key_buf),
135 .key = public_key_buf,
139 size_t shared_secret_words = kP256SharedSecretBytes /
sizeof(uint32_t);
140 uint32_t shared_secretblob[shared_secret_words * 2];
141 memset(shared_secretblob, 0,
sizeof(shared_secretblob));
145 .version = kOtcryptoLibVersion1,
146 .key_mode = kOtcryptoKeyModeAesCtr,
147 .key_length = kP256SharedSecretBytes,
150 .security_level = kOtcryptoKeySecurityLevelLow,
152 .keyblob_length =
sizeof(shared_secretblob),
153 .keyblob = shared_secretblob,
159 case kOtcryptoStatusValueOk: {
163 case kOtcryptoStatusValueBadArgs: {
174 uint32_t share0[shared_secret_words];
175 uint32_t share1[shared_secret_words];
180 for (
size_t i = 0; i < shared_secret_words; i++) {
181 ss[i] = share0[i] ^ share1[i];
202 static status_t ecdh_p384(cryptotest_ecdh_private_key_t d,
203 cryptotest_ecdh_coordinate_t qx,
204 cryptotest_ecdh_coordinate_t qy, uint32_t *ss,
206 if (d.d0_len > kP384MaskedPrivateKeyBytes ||
207 d.d1_len > kP384MaskedPrivateKeyBytes) {
209 "Bad P-384 private key share length (should both be <= %d): (d0 = %d, "
212 kP384PrivateKeyBytes, d.d0_len, d.d1_len);
213 return INVALID_ARGUMENT();
215 if (qx.coordinate_len > kP384CoordinateBytes ||
216 qy.coordinate_len > kP384CoordinateBytes) {
218 "Bad P-384 coordinate length (should both be <= %d): (x = %d, y = %d)",
219 kP384CoordinateBytes, qx.coordinate_len, qy.coordinate_len);
220 return INVALID_ARGUMENT();
227 uint32_t private_keyblob[kP384MaskedPrivateKeyWords * 2];
228 memset(private_keyblob, 0,
sizeof(private_keyblob));
229 memcpy(private_keyblob, d.d0, d.d0_len);
230 memcpy(private_keyblob + kP384MaskedPrivateKeyWords, d.d1, d.d1_len);
234 .version = kOtcryptoLibVersion1,
235 .key_mode = kOtcryptoKeyModeEcdhP384,
236 .key_length = kP384PrivateKeyBytes,
239 .security_level = kOtcryptoKeySecurityLevelLow,
241 .keyblob_length =
sizeof(private_keyblob),
242 .keyblob = private_keyblob,
248 uint32_t public_key_buf[kP384CoordinateWords * 2];
249 memset(public_key_buf, 0,
sizeof(public_key_buf));
250 memcpy(public_key_buf, qx.coordinate, qx.coordinate_len);
251 memcpy(public_key_buf + kP384CoordinateWords, qy.coordinate,
254 .key_mode = kOtcryptoKeyModeEcdhP384,
255 .key_length =
sizeof(public_key_buf),
256 .key = public_key_buf,
260 size_t shared_secret_words = kP384SharedSecretBytes /
sizeof(uint32_t);
261 uint32_t shared_secretblob[shared_secret_words * 2];
262 memset(shared_secretblob, 0,
sizeof(shared_secretblob));
266 .version = kOtcryptoLibVersion1,
267 .key_mode = kOtcryptoKeyModeAesCtr,
268 .key_length = kP384SharedSecretBytes,
271 .security_level = kOtcryptoKeySecurityLevelLow,
273 .keyblob_length =
sizeof(shared_secretblob),
274 .keyblob = shared_secretblob,
280 case kOtcryptoStatusValueOk: {
284 case kOtcryptoStatusValueBadArgs: {
295 uint32_t share0[shared_secret_words];
296 uint32_t share1[shared_secret_words];
301 for (
size_t i = 0; i < shared_secret_words; i++) {
302 ss[i] = share0[i] ^ share1[i];
309 cryptotest_ecdh_curve_t uj_curve;
310 cryptotest_ecdh_private_key_t uj_private_key;
311 cryptotest_ecdh_coordinate_t uj_qx;
312 cryptotest_ecdh_coordinate_t uj_qy;
315 TRY(ujson_deserialize_cryptotest_ecdh_curve_t(uj, &uj_curve));
316 TRY(ujson_deserialize_cryptotest_ecdh_private_key_t(uj, &uj_private_key));
317 TRY(ujson_deserialize_cryptotest_ecdh_coordinate_t(uj, &uj_qx));
318 TRY(ujson_deserialize_cryptotest_ecdh_coordinate_t(uj, &uj_qy));
320 cryptotest_ecdh_derive_output_t uj_output;
323 case kCryptotestEcdhCurveP256: {
324 uint32_t shared_secret_words[kP256SharedSecretBytes /
sizeof(uint32_t)];
325 TRY(ecdh_p256(uj_private_key, uj_qx, uj_qy, shared_secret_words, &valid));
326 memcpy(uj_output.shared_secret, shared_secret_words,
327 kP256SharedSecretBytes);
328 uj_output.shared_secret_len = kP256SharedSecretBytes;
331 case kCryptotestEcdhCurveP384: {
332 uint32_t shared_secret_words[kP384SharedSecretBytes /
sizeof(uint32_t)];
333 TRY(ecdh_p384(uj_private_key, uj_qx, uj_qy, shared_secret_words, &valid));
334 memcpy(uj_output.shared_secret, shared_secret_words,
335 kP384SharedSecretBytes);
336 uj_output.shared_secret_len = kP384SharedSecretBytes;
340 LOG_ERROR(
"Unsupported ECC curve: %d", uj_curve);
341 return INVALID_ARGUMENT();
343 uj_output.ok = (uint8_t)valid;
345 RESP_OK(ujson_serialize_cryptotest_ecdh_derive_output_t, uj, &uj_output);