Fixed modular reduction bug in the special field for P-256 (in some rare cases, value...
[BearSSL] / test / test_crypto.c
index 47c6bf6..ae0c712 100644 (file)
@@ -3133,6 +3133,71 @@ test_AES_generic(char *name,
                        check_equals("KAT CBC AES decrypt (2)",
                                buf, plain, data_len);
                }
                        check_equals("KAT CBC AES decrypt (2)",
                                buf, plain, data_len);
                }
+
+               /*
+                * We want to check proper IV management for CBC:
+                * encryption and decryption must properly copy the _last_
+                * encrypted block as new IV, for all sizes.
+                */
+               for (u = 1; u <= 35; u ++) {
+                       br_hmac_drbg_context rng;
+                       unsigned char x;
+                       size_t key_len, data_len;
+                       size_t v;
+
+                       br_hmac_drbg_init(&rng, &br_sha256_vtable,
+                               "seed for AES/CBC", 16);
+                       x = u;
+                       br_hmac_drbg_update(&rng, &x, 1);
+                       data_len = u << 4;
+                       for (key_len = 16; key_len <= 32; key_len += 16) {
+                               unsigned char key[32];
+                               unsigned char iv[16], iv1[16], iv2[16];
+                               unsigned char plain[35 * 16];
+                               unsigned char tmp1[sizeof plain];
+                               unsigned char tmp2[sizeof plain];
+                               br_aes_gen_cbcenc_keys v_ec;
+                               br_aes_gen_cbcdec_keys v_dc;
+                               const br_block_cbcenc_class **ec;
+                               const br_block_cbcdec_class **dc;
+
+                               br_hmac_drbg_generate(&rng, key, key_len);
+                               br_hmac_drbg_generate(&rng, iv, sizeof iv);
+                               br_hmac_drbg_generate(&rng, plain, data_len);
+
+                               ec = &v_ec.vtable;
+                               ve->init(ec, key, key_len);
+                               memcpy(iv1, iv, sizeof iv);
+                               memcpy(tmp1, plain, data_len);
+                               ve->run(ec, iv1, tmp1, data_len);
+                               check_equals("IV CBC AES (1)",
+                                       tmp1 + data_len - 16, iv1, 16);
+                               memcpy(iv2, iv, sizeof iv);
+                               memcpy(tmp2, plain, data_len);
+                               for (v = 0; v < data_len; v += 16) {
+                                       ve->run(ec, iv2, tmp2 + v, 16);
+                               }
+                               check_equals("IV CBC AES (2)",
+                                       tmp2 + data_len - 16, iv2, 16);
+                               check_equals("IV CBC AES (3)",
+                                       tmp1, tmp2, data_len);
+
+                               dc = &v_dc.vtable;
+                               vd->init(dc, key, key_len);
+                               memcpy(iv1, iv, sizeof iv);
+                               vd->run(dc, iv1, tmp1, data_len);
+                               check_equals("IV CBC AES (4)", iv1, iv2, 16);
+                               check_equals("IV CBC AES (5)",
+                                       tmp1, plain, data_len);
+                               memcpy(iv2, iv, sizeof iv);
+                               for (v = 0; v < data_len; v += 16) {
+                                       vd->run(dc, iv2, tmp2 + v, 16);
+                               }
+                               check_equals("IV CBC AES (6)", iv1, iv2, 16);
+                               check_equals("IV CBC AES (7)",
+                                       tmp2, plain, data_len);
+                       }
+               }
        }
 
        if (vc != NULL) {
        }
 
        if (vc != NULL) {
@@ -4997,6 +5062,39 @@ test_EC_inner(const char *sk, const char *sU,
        fflush(stdout);
 }
 
        fflush(stdout);
 }
 
+static void
+test_EC_P256_carry_inner(const br_ec_impl *impl, const char *sP, const char *sQ)
+{
+       unsigned char P[65], Q[sizeof P], k[1];
+       size_t plen, qlen;
+
+       plen = hextobin(P, sP);
+       qlen = hextobin(Q, sQ);
+       if (plen != sizeof P || qlen != sizeof P) {
+               fprintf(stderr, "KAT is incorrect\n");
+               exit(EXIT_FAILURE);
+       }
+       k[0] = 0x10;
+       if (impl->mul(P, plen, k, 1, BR_EC_secp256r1) != 1) {
+               fprintf(stderr, "P-256 multiplication failed\n");
+               exit(EXIT_FAILURE);
+       }
+       check_equals("P256_carry", P, Q, plen);
+       printf(".");
+       fflush(stdout);
+}
+
+static void
+test_EC_P256_carry(const br_ec_impl *impl)
+{
+       test_EC_P256_carry_inner(impl,
+               "0435BAA24B2B6E1B3C88E22A383BD88CC4B9A3166E7BCF94FF6591663AE066B33B821EBA1B4FC8EA609A87EB9A9C9A1CCD5C9F42FA1365306F64D7CAA718B8C978",
+               "0447752A76CA890328D34E675C4971EC629132D1FC4863EDB61219B72C4E58DC5E9D51E7B293488CFD913C3CF20E438BB65C2BA66A7D09EABB45B55E804260C5EB");
+       test_EC_P256_carry_inner(impl,
+               "04DCAE9D9CE211223602024A6933BD42F77B6BF4EAB9C8915F058C149419FADD2CC9FC0707B270A1B5362BA4D249AFC8AC3DA1EFCA8270176EEACA525B49EE19E6",
+               "048DAC7B0BE9B3206FCE8B24B6B4AEB122F2A67D13E536B390B6585CA193427E63F222388B5F51D744D6F5D47536D89EEEC89552BCB269E7828019C4410DFE980A");
+}
+
 static void
 test_EC_KAT(const char *name, const br_ec_impl *impl, uint32_t curve_mask)
 {
 static void
 test_EC_KAT(const char *name, const br_ec_impl *impl, uint32_t curve_mask)
 {
@@ -5009,6 +5107,7 @@ test_EC_KAT(const char *name, const br_ec_impl *impl, uint32_t curve_mask)
                        "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
                        "0460FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
                        impl, BR_EC_secp256r1);
                        "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
                        "0460FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB67903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
                        impl, BR_EC_secp256r1);
+               test_EC_P256_carry(impl);
        }
        if (curve_mask & ((uint32_t)1 << BR_EC_secp384r1)) {
                test_EC_inner(
        }
        if (curve_mask & ((uint32_t)1 << BR_EC_secp384r1)) {
                test_EC_inner(