X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=test%2Ftest_crypto.c;h=dd2562cbadc2c42cac530093f924bf7b1593e92b;hp=acfabd05791911135bd8a2a6b32718598505f5d4;hb=f8e38c231dab636d8a1ece7f9eaa07bf09dfb049;hpb=491a45337de8dc0a4c100abf33f5c0e187a08afd diff --git a/test/test_crypto.c b/test/test_crypto.c index acfabd0..dd2562c 100644 --- a/test/test_crypto.c +++ b/test/test_crypto.c @@ -1074,6 +1074,41 @@ test_HMAC_DRBG(void) fflush(stdout); } +static void +test_AESCTR_DRBG(void) +{ + br_aesctr_drbg_context ctx; + const br_block_ctr_class *ictr; + unsigned char tmp1[64], tmp2[64]; + + printf("Test AESCTR_DRBG: "); + fflush(stdout); + + ictr = br_aes_x86ni_ctr_get_vtable(); + if (ictr == NULL) { + ictr = br_aes_pwr8_ctr_get_vtable(); + if (ictr == NULL) { +#if BR_64 + ictr = &br_aes_ct64_ctr_vtable; +#else + ictr = &br_aes_ct_ctr_vtable; +#endif + } + } + br_aesctr_drbg_init(&ctx, ictr, NULL, 0); + ctx.vtable->generate(&ctx.vtable, tmp1, sizeof tmp1); + ctx.vtable->update(&ctx.vtable, "new seed", 8); + ctx.vtable->generate(&ctx.vtable, tmp2, sizeof tmp2); + + if (memcmp(tmp1, tmp2, sizeof tmp1) == 0) { + fprintf(stderr, "AESCTR_DRBG failure\n"); + exit(EXIT_FAILURE); + } + + printf("done.\n"); + fflush(stdout); +} + static void do_KAT_PRF(br_tls_prf_impl prf, const char *ssecret, const char *label, const char *sseed, @@ -3629,6 +3664,19 @@ test_AES_CTRCBC_x86ni(void) } } +static void +test_AES_CTRCBC_pwr8(void) +{ + const br_block_ctrcbc_class *vt; + + vt = br_aes_pwr8_ctrcbc_get_vtable(); + if (vt != NULL) { + test_AES_CTRCBC_inner("pwr8", vt); + } else { + printf("Test AES CTR/CBC-MAC pwr8: UNAVAILABLE\n"); + } +} + /* * DES known-answer tests. Order: plaintext, key, ciphertext. * (mostly from NIST SP 800-20). @@ -5686,8 +5734,9 @@ test_RSA_OAEP(const char *name, } static void -test_RSA_keygen(const char *name, br_rsa_keygen kg, - br_rsa_pkcs1_sign sign, br_rsa_pkcs1_vrfy vrfy) +test_RSA_keygen(const char *name, br_rsa_keygen kg, br_rsa_compute_modulus cm, + br_rsa_compute_pubexp ce, br_rsa_compute_privexp cd, + br_rsa_public pub, br_rsa_pkcs1_sign sign, br_rsa_pkcs1_vrfy vrfy) { br_hmac_drbg_context rng; int i; @@ -5697,25 +5746,30 @@ test_RSA_keygen(const char *name, br_rsa_keygen kg, br_hmac_drbg_init(&rng, &br_sha256_vtable, "seed for RSA keygen", 19); - for (i = 0; i < 40; i ++) { + for (i = 0; i <= 42; i ++) { unsigned size; - uint32_t pubexp; + uint32_t pubexp, z; br_rsa_private_key sk; - br_rsa_public_key pk; + br_rsa_public_key pk, pk2; unsigned char kbuf_priv[BR_RSA_KBUF_PRIV_SIZE(2048)]; unsigned char kbuf_pub[BR_RSA_KBUF_PUB_SIZE(2048)]; + unsigned char n2[256], d[256], msg1[256], msg2[256]; uint32_t mod[256]; uint32_t cc; size_t u, v; unsigned char sig[257], hv[32], hv2[sizeof hv]; unsigned mask1, mask2; + int j; if (i <= 35) { size = 1024 + i; pubexp = 17; - } else { + } else if (i <= 40) { size = 2048; pubexp = (i << 1) - 69; + } else { + size = 2048; + pubexp = 0xFFFFFFFF; } if (!kg(&rng.vtable, @@ -5725,14 +5779,15 @@ test_RSA_keygen(const char *name, br_rsa_keygen kg, exit(EXIT_FAILURE); } + z = pubexp; for (u = pk.elen; u > 0; u --) { - if (pk.e[u - 1] != (pubexp & 0xFF)) { + if (pk.e[u - 1] != (z & 0xFF)) { fprintf(stderr, "wrong public exponent\n"); exit(EXIT_FAILURE); } - pubexp >>= 8; + z >>= 8; } - if (pubexp != 0) { + if (z != 0) { fprintf(stderr, "truncated public exponent\n"); exit(EXIT_FAILURE); } @@ -5771,28 +5826,86 @@ test_RSA_keygen(const char *name, br_rsa_keygen kg, exit(EXIT_FAILURE); } - rng.vtable->generate(&rng.vtable, hv, sizeof hv); - memset(sig, 0, sizeof sig); - sig[pk.nlen] = 0x00; - if (!sign(BR_HASH_OID_SHA256, hv, sizeof hv, &sk, sig)) { - fprintf(stderr, "signature error\n"); + if (cm(NULL, &sk) != pk.nlen) { + fprintf(stderr, "wrong recomputed modulus length\n"); exit(EXIT_FAILURE); } - if (sig[pk.nlen] != 0x00) { - fprintf(stderr, "signature length error\n"); + if (cm(n2, &sk) != pk.nlen || memcmp(pk.n, n2, pk.nlen) != 0) { + fprintf(stderr, "wrong recomputed modulus value\n"); exit(EXIT_FAILURE); } - if (!vrfy(sig, pk.nlen, BR_HASH_OID_SHA256, sizeof hv, - &pk, hv2)) - { - fprintf(stderr, "signature verification error (1)\n"); + + z = ce(&sk); + if (z != pubexp) { + fprintf(stderr, + "wrong recomputed pubexp: %lu (exp: %lu)\n", + (unsigned long)z, (unsigned long)pubexp); + exit(EXIT_FAILURE); + } + + if (cd(NULL, &sk, pubexp) != pk.nlen) { + fprintf(stderr, + "wrong recomputed privexp length (1)\n"); + exit(EXIT_FAILURE); + } + if (cd(d, &sk, pubexp) != pk.nlen) { + fprintf(stderr, + "wrong recomputed privexp length (2)\n"); + exit(EXIT_FAILURE); + } + /* + * To check that the private exponent is correct, we make + * it into a _public_ key, and use the public-key operation + * to perform the modular exponentiation. + */ + pk2 = pk; + pk2.e = d; + pk2.elen = pk.nlen; + rng.vtable->generate(&rng.vtable, msg1, pk.nlen); + msg1[0] = 0x00; + memcpy(msg2, msg1, pk.nlen); + if (!pub(msg2, pk.nlen, &pk2) || !pub(msg2, pk.nlen, &pk)) { + fprintf(stderr, "public-key operation error\n"); exit(EXIT_FAILURE); } - if (memcmp(hv, hv2, sizeof hv) != 0) { - fprintf(stderr, "signature verification error (2)\n"); + if (memcmp(msg1, msg2, pk.nlen) != 0) { + fprintf(stderr, "wrong recomputed privexp\n"); exit(EXIT_FAILURE); } + /* + * We test the RSA operation over a some random messages. + */ + for (j = 0; j < 20; j ++) { + rng.vtable->generate(&rng.vtable, hv, sizeof hv); + memset(sig, 0, sizeof sig); + sig[pk.nlen] = 0x00; + if (!sign(BR_HASH_OID_SHA256, + hv, sizeof hv, &sk, sig)) + { + fprintf(stderr, + "signature error (%d)\n", j); + exit(EXIT_FAILURE); + } + if (sig[pk.nlen] != 0x00) { + fprintf(stderr, + "signature length error (%d)\n", j); + exit(EXIT_FAILURE); + } + if (!vrfy(sig, pk.nlen, BR_HASH_OID_SHA256, sizeof hv, + &pk, hv2)) + { + fprintf(stderr, + "signature verif error (%d)\n", j); + exit(EXIT_FAILURE); + } + if (memcmp(hv, hv2, sizeof hv) != 0) { + fprintf(stderr, + "signature extract error (%d)\n", j); + exit(EXIT_FAILURE); + } + } + printf("."); fflush(stdout); } @@ -5810,6 +5923,8 @@ test_RSA_i15(void) test_RSA_OAEP("RSA i15 OAEP", &br_rsa_i15_oaep_encrypt, &br_rsa_i15_oaep_decrypt); test_RSA_keygen("RSA i15 keygen", &br_rsa_i15_keygen, + &br_rsa_i15_compute_modulus, &br_rsa_i15_compute_pubexp, + &br_rsa_i15_compute_privexp, &br_rsa_i15_public, &br_rsa_i15_pkcs1_sign, &br_rsa_i15_pkcs1_vrfy); } @@ -5822,6 +5937,8 @@ test_RSA_i31(void) test_RSA_OAEP("RSA i31 OAEP", &br_rsa_i31_oaep_encrypt, &br_rsa_i31_oaep_decrypt); test_RSA_keygen("RSA i31 keygen", &br_rsa_i31_keygen, + &br_rsa_i31_compute_modulus, &br_rsa_i31_compute_pubexp, + &br_rsa_i31_compute_privexp, &br_rsa_i31_public, &br_rsa_i31_pkcs1_sign, &br_rsa_i31_pkcs1_vrfy); } @@ -5861,7 +5978,10 @@ test_RSA_i62(void) test_RSA_core("RSA i62 core", pub, priv); test_RSA_sign("RSA i62 sign", priv, sign, vrfy); test_RSA_OAEP("RSA i62 OAEP", menc, mdec); - test_RSA_keygen("RSA i62 keygen", kgen, sign, vrfy); + test_RSA_keygen("RSA i62 keygen", kgen, + &br_rsa_i31_compute_modulus, &br_rsa_i31_compute_pubexp, + &br_rsa_i31_compute_privexp, pub, + sign, vrfy); } else { if (priv || sign || vrfy || menc || mdec || kgen) { fprintf(stderr, "Inconsistent i62 availability\n"); @@ -6732,6 +6852,13 @@ test_EAX(void) } else { printf("Test EAX aes_x86ni: UNAVAILABLE\n"); } + + x_ctrcbc = br_aes_pwr8_ctrcbc_get_vtable(); + if (x_ctrcbc != NULL) { + test_EAX_inner("aes_pwr8", x_ctrcbc); + } else { + printf("Test EAX aes_pwr8: UNAVAILABLE\n"); + } } /* @@ -6944,6 +7071,13 @@ test_CCM(void) } else { printf("Test CCM aes_x86ni: UNAVAILABLE\n"); } + + x_ctrcbc = br_aes_pwr8_ctrcbc_get_vtable(); + if (x_ctrcbc != NULL) { + test_CCM_inner("aes_pwr8", x_ctrcbc); + } else { + printf("Test CCM aes_pwr8: UNAVAILABLE\n"); + } } static void @@ -7174,7 +7308,6 @@ test_EC_P256_carry(const br_ec_impl *impl) static void test_EC_KAT(const char *name, const br_ec_impl *impl, uint32_t curve_mask) { - printf("Test %s: ", name); fflush(stdout); @@ -7202,6 +7335,155 @@ test_EC_KAT(const char *name, const br_ec_impl *impl, uint32_t curve_mask) fflush(stdout); } +static void +test_EC_keygen(const char *name, const br_ec_impl *impl, uint32_t curves) +{ + int curve; + br_hmac_drbg_context rng; + + printf("Test %s keygen: ", name); + fflush(stdout); + + br_hmac_drbg_init(&rng, &br_sha256_vtable, "seed for EC keygen", 18); + br_hmac_drbg_update(&rng, name, strlen(name)); + + for (curve = -1; curve <= 35; curve ++) { + br_ec_private_key sk; + br_ec_public_key pk; + unsigned char kbuf_priv[BR_EC_KBUF_PRIV_MAX_SIZE]; + unsigned char kbuf_pub[BR_EC_KBUF_PUB_MAX_SIZE]; + + if (curve < 0 || curve >= 32 || ((curves >> curve) & 1) == 0) { + if (br_ec_keygen(&rng.vtable, impl, + &sk, kbuf_priv, curve) != 0) + { + fprintf(stderr, "br_ec_keygen() did not" + " reject unsupported curve %d\n", + curve); + exit(EXIT_FAILURE); + } + sk.curve = curve; + if (br_ec_compute_pub(impl, NULL, NULL, &sk) != 0) { + fprintf(stderr, "br_ec_keygen() did not" + " reject unsupported curve %d\n", + curve); + exit(EXIT_FAILURE); + } + } else { + size_t len, u; + unsigned char tmp_priv[sizeof kbuf_priv]; + unsigned char tmp_pub[sizeof kbuf_pub]; + unsigned z; + + len = br_ec_keygen(&rng.vtable, impl, + NULL, NULL, curve); + if (len == 0) { + fprintf(stderr, "br_ec_keygen() rejects" + " supported curve %d\n", curve); + exit(EXIT_FAILURE); + } + if (len > sizeof kbuf_priv) { + fprintf(stderr, "oversized kbuf_priv\n"); + exit(EXIT_FAILURE); + } + memset(kbuf_priv, 0, sizeof kbuf_priv); + if (br_ec_keygen(&rng.vtable, impl, + NULL, kbuf_priv, curve) != len) + { + fprintf(stderr, "kbuf_priv length mismatch\n"); + exit(EXIT_FAILURE); + } + z = 0; + for (u = 0; u < len; u ++) { + z |= kbuf_priv[u]; + } + if (z == 0) { + fprintf(stderr, "kbuf_priv not initialized\n"); + exit(EXIT_FAILURE); + } + for (u = len; u < sizeof kbuf_priv; u ++) { + if (kbuf_priv[u] != 0) { + fprintf(stderr, "kbuf_priv overflow\n"); + exit(EXIT_FAILURE); + } + } + if (br_ec_keygen(&rng.vtable, impl, + NULL, tmp_priv, curve) != len) + { + fprintf(stderr, "tmp_priv length mismatch\n"); + exit(EXIT_FAILURE); + } + if (memcmp(kbuf_priv, tmp_priv, len) == 0) { + fprintf(stderr, "keygen stutter\n"); + exit(EXIT_FAILURE); + } + memset(&sk, 0, sizeof sk); + if (br_ec_keygen(&rng.vtable, impl, + &sk, kbuf_priv, curve) != len) + { + fprintf(stderr, + "kbuf_priv length mismatch (2)\n"); + exit(EXIT_FAILURE); + } + if (sk.curve != curve || sk.x != kbuf_priv + || sk.xlen != len) + { + fprintf(stderr, "sk not initialized\n"); + exit(EXIT_FAILURE); + } + + len = br_ec_compute_pub(impl, NULL, NULL, &sk); + if (len > sizeof kbuf_pub) { + fprintf(stderr, "oversized kbuf_pub\n"); + exit(EXIT_FAILURE); + } + memset(kbuf_pub, 0, sizeof kbuf_pub); + if (br_ec_compute_pub(impl, NULL, + kbuf_pub, &sk) != len) + { + fprintf(stderr, "kbuf_pub length mismatch\n"); + exit(EXIT_FAILURE); + } + for (u = len; u < sizeof kbuf_pub; u ++) { + if (kbuf_pub[u] != 0) { + fprintf(stderr, "kbuf_pub overflow\n"); + exit(EXIT_FAILURE); + } + } + memset(&pk, 0, sizeof pk); + if (br_ec_compute_pub(impl, &pk, + tmp_pub, &sk) != len) + { + fprintf(stderr, "tmp_pub length mismatch\n"); + exit(EXIT_FAILURE); + } + if (memcmp(kbuf_pub, tmp_pub, len) != 0) { + fprintf(stderr, "pubkey mismatch\n"); + exit(EXIT_FAILURE); + } + if (pk.curve != curve || pk.q != tmp_pub + || pk.qlen != len) + { + fprintf(stderr, "pk not initialized\n"); + exit(EXIT_FAILURE); + } + + if (impl->mulgen(kbuf_pub, + sk.x, sk.xlen, curve) != len + || memcmp(pk.q, kbuf_pub, len) != 0) + { + fprintf(stderr, "wrong pubkey\n"); + exit(EXIT_FAILURE); + } + } + printf("."); + fflush(stdout); + } + + printf(" done.\n"); + fflush(stdout); +} + static void test_EC_prime_i15(void) { @@ -7209,6 +7491,10 @@ test_EC_prime_i15(void) (uint32_t)1 << BR_EC_secp256r1 | (uint32_t)1 << BR_EC_secp384r1 | (uint32_t)1 << BR_EC_secp521r1); + test_EC_keygen("EC_prime_i15", &br_ec_prime_i15, + (uint32_t)1 << BR_EC_secp256r1 + | (uint32_t)1 << BR_EC_secp384r1 + | (uint32_t)1 << BR_EC_secp521r1); } static void @@ -7218,6 +7504,10 @@ test_EC_prime_i31(void) (uint32_t)1 << BR_EC_secp256r1 | (uint32_t)1 << BR_EC_secp384r1 | (uint32_t)1 << BR_EC_secp521r1); + test_EC_keygen("EC_prime_i31", &br_ec_prime_i31, + (uint32_t)1 << BR_EC_secp256r1 + | (uint32_t)1 << BR_EC_secp384r1 + | (uint32_t)1 << BR_EC_secp521r1); } static void @@ -7225,6 +7515,8 @@ test_EC_p256_m15(void) { test_EC_KAT("EC_p256_m15", &br_ec_p256_m15, (uint32_t)1 << BR_EC_secp256r1); + test_EC_keygen("EC_p256_m15", &br_ec_p256_m15, + (uint32_t)1 << BR_EC_secp256r1); } static void @@ -7232,6 +7524,8 @@ test_EC_p256_m31(void) { test_EC_KAT("EC_p256_m31", &br_ec_p256_m31, (uint32_t)1 << BR_EC_secp256r1); + test_EC_keygen("EC_p256_m31", &br_ec_p256_m31, + (uint32_t)1 << BR_EC_secp256r1); } const struct { @@ -7318,24 +7612,32 @@ static void test_EC_c25519_i15(void) { test_EC_c25519("EC_c25519_i15", &br_ec_c25519_i15); + test_EC_keygen("EC_c25519_i15", &br_ec_c25519_i15, + (uint32_t)1 << BR_EC_curve25519); } static void test_EC_c25519_i31(void) { test_EC_c25519("EC_c25519_i31", &br_ec_c25519_i31); + test_EC_keygen("EC_c25519_i31", &br_ec_c25519_i31, + (uint32_t)1 << BR_EC_curve25519); } static void test_EC_c25519_m15(void) { test_EC_c25519("EC_c25519_m15", &br_ec_c25519_m15); + test_EC_keygen("EC_c25519_m15", &br_ec_c25519_m15, + (uint32_t)1 << BR_EC_curve25519); } static void test_EC_c25519_m31(void) { test_EC_c25519("EC_c25519_m31", &br_ec_c25519_m31); + test_EC_keygen("EC_c25519_m31", &br_ec_c25519_m31, + (uint32_t)1 << BR_EC_curve25519); } static const unsigned char EC_P256_PUB_POINT[] = { @@ -7965,6 +8267,7 @@ static const struct { STU(multihash), STU(HMAC), STU(HMAC_DRBG), + STU(AESCTR_DRBG), STU(PRF), STU(AES_big), STU(AES_small), @@ -7977,6 +8280,7 @@ static const struct { STU(AES_CTRCBC_ct), STU(AES_CTRCBC_ct64), STU(AES_CTRCBC_x86ni), + STU(AES_CTRCBC_pwr8), STU(DES_tab), STU(DES_ct), STU(ChaCha20_ct),