/* Copyright (c) (2016,2018,2019,2020) Apple Inc. All rights reserved. * * corecrypto is licensed under Apple Inc.’s Internal Use License Agreement (which * is contained in the License.txt file distributed with corecrypto) and only to * people who accept that license. IMPORTANT: Any license rights granted to you by * Apple Inc. (if any) are limited to internal use within your organization only on * devices and computers you own or control, for the sole purpose of verifying the * security characteristics and correct functioning of the Apple Software. You may * not, directly or indirectly, redistribute the Apple Software or any portions thereof. */ #include #include #include #include #include #include #include "crypto_test_rsapkcs1v15.h" #include "testmore.h" struct ccrsa_verify_vector { const struct ccdigest_info *di; unsigned long modlen; // in bits const void *mod; cc_unit exp; const void *digest; /* length governed by di */ unsigned long msglen; // in bytes const void *msg; unsigned long siglen; // in bytes - should be modlen/8 const void *sig; bool valid; // expected result }; static int ccrsa_test_verify_pkcs1v15_vector(const struct ccrsa_verify_vector *v) { bool ok; int rc; const struct ccdigest_info *di = v->di; const cc_size n = ccn_nof(v->modlen); const size_t s = ccn_sizeof(v->modlen); unsigned char H[di->output_size]; const uint8_t *sig = v->sig; unsigned long siglen = v->siglen; uint8_t canary_out[sizeof(CCRSA_PKCS1_FAULT_CANARY)]; cc_unit exponent[n]; cc_unit modulus[n]; ccrsa_pub_ctx_decl(ccn_sizeof(v->modlen), key); ccrsa_ctx_n(key) = n; ccn_seti(n, exponent, v->exp); ccn_read_uint(n, modulus, s, v->mod); ccrsa_init_pub(key, modulus, exponent); if (v->digest) { memcpy(H, v->digest, sizeof(H)); } else { ccdigest(di, v->msglen, v->msg, H); } ok = !v->valid; rc = ccrsa_verify_pkcs1v15(key, di->oid, di->output_size, H, siglen, sig, &ok); if (rc || (ok != v->valid)) { return -1; } rc = ccrsa_verify_pkcs1v15_digest(key, di->oid, di->output_size, H, siglen, sig, canary_out); if ((v->valid && rc != CCERR_VALID_SIGNATURE) || (!v->valid && rc == CCERR_VALID_SIGNATURE)) { return -1; } if (v->valid && memcmp(canary_out, CCRSA_PKCS1_FAULT_CANARY, sizeof(CCRSA_PKCS1_FAULT_CANARY)) != 0) { return -1; } if (!v->digest) { rc = ccrsa_verify_pkcs1v15_msg(key, di, v->msglen, v->msg, siglen, sig, canary_out); if ((v->valid && rc != CCERR_VALID_SIGNATURE) || (!v->valid && rc == CCERR_VALID_SIGNATURE)) { return -1; } if (v->valid && memcmp(canary_out, CCRSA_PKCS1_FAULT_CANARY, sizeof(CCRSA_PKCS1_FAULT_CANARY)) != 0) { return -1; } } while (siglen > 0 && sig[0] == 0) { sig += 1; siglen -= 1; ok = true; rc = ccrsa_verify_pkcs1v15(key, di->oid, di->output_size, H, siglen, sig, &ok); if (!rc || ok) { return -1; } ok = !v->valid; rc = ccrsa_verify_pkcs1v15_allowshortsigs(key, di->oid, di->output_size, H, siglen, sig, &ok); if (rc || (ok != v->valid)) { return -1; } } return 0; } /* Nist CAVP vectors specifies the hash as strings - those are matching hashes implementations */ /* We picked the implementations that are on all platform, it does not matter since we are not testing the hash here */ #define di_SHA1 &ccsha1_eay_di #define di_SHA224 &ccsha224_ltc_di #define di_SHA256 &ccsha256_ltc_di #define di_SHA384 &ccsha384_ltc_di #define di_SHA512 &ccsha512_ltc_di /* Nist CAVP vectors for verify specify the result as F (failed) or P (passed) those translate as true or false */ #define P true #define F false const struct ccrsa_verify_vector verify_vectors_pkcs1v15[] = { #include "../test_vectors/SigVer15.inc" }; int test_verify_pkcs1v15_known_answer_test(void) { uint32_t i; uint32_t nb_test_passed, nb_test; nb_test_passed = 0; nb_test = 0; // Run only tests for supported hash algorithms for (i = 0; i < sizeof(verify_vectors_pkcs1v15) / sizeof(struct ccrsa_verify_vector); i++) { if (verify_vectors_pkcs1v15[i].di != NULL) { // 1 bit is set to one when the test passed nb_test++; if (ccrsa_test_verify_pkcs1v15_vector(&verify_vectors_pkcs1v15[i]) == 0) { nb_test_passed += 1; } } } if ((nb_test_passed == nb_test) && (nb_test > 0)) { return 0; } return -1; }