corecrypto/ccrsa/crypto_test/crypto_test_rsapkcs1v15.c

145 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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 <corecrypto/ccrsa_priv.h>
#include <corecrypto/ccrsa.h>
#include <corecrypto/ccdigest.h>
#include <corecrypto/ccsha1.h>
#include <corecrypto/ccrng_sequence.h>
#include <corecrypto/ccsha2.h>
#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;
}