/* Copyright (c) (2012,2014,2015,2016,2018,2019) 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 "testmore.h" #include "testbyteBuffer.h" #include "testccnBuffer.h" static int verbose = 0; #if (CCHMAC == 0) entryPoint(cchmac_tests,"cchmac test") #else #include #include #include #include #include #include #include #include #include #include /* Currently, cchmac and friends won't work when length == 0 and the * data pointer is NULL. */ #define keystr128 "000102030405060708090a0b0c0d0e0f" #define HMAC_DATA_POINTER_NULL_TOLERANT 0 typedef struct test_vector_t { char *keyStr; uint8_t *data; size_t data_len; char *md2_answer; char *md4_answer; char *md5_answer; char *sha1_answer; char *sha224_answer; char *sha256_answer; char *sha384_answer; char *sha512_answer; char *rmd160_answer; } test_vector; static char * digest_name(const struct ccdigest_info *di) { if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD2)) return "MD2"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD4)) return "MD4"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD5)) return "MD5"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA1)) return "SHA1"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA224)) return "SHA224"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA256)) return "SHA256"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA384)) return "SHA384"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA512)) return "SHA512"; if(ccdigest_oid_equal(di, CC_DIGEST_OID_RMD160)) return "RMD160"; return NULL; } static int test_answer(const struct ccdigest_info *di, test_vector *vector, void*answer) { char *correct_answer = NULL; if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD2)) correct_answer = vector->md2_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD4)) correct_answer = vector->md4_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_MD5)) correct_answer = vector->md5_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA1)) correct_answer = vector->sha1_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA224)) correct_answer = vector->sha224_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA256)) correct_answer = vector->sha256_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA384)) correct_answer = vector->sha384_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_SHA512)) correct_answer = vector->sha512_answer; else if(ccdigest_oid_equal(di, CC_DIGEST_OID_RMD160)) correct_answer = vector->rmd160_answer; byteBuffer answer_bb = bytesToBytes(answer, di->output_size); if(correct_answer == NULL) { diag("Digest %s: ", digest_name(di)); cc_print("Output value",answer_bb->len,answer_bb->bytes); return 1; } byteBuffer correct_answer_bb = hexStringToBytes((char *) correct_answer); ok(bytesAreEqual(correct_answer_bb, answer_bb), "compare memory of answer"); if(bytesAreEqual(correct_answer_bb, answer_bb) == 0) { printByteBuffer(correct_answer_bb, "Correct Answer"); printByteBuffer(answer_bb, "Provided Answer"); } free(correct_answer_bb); free(answer_bb); return 1; } static int guard_ok(uint8_t *p, int chr, size_t len) { for(size_t i=0; idata_len; size_t chunk = vector->data_len/2; uint8_t *p = vector->data; uint8_t ctxfrontguard[4096]; cchmac_di_decl(di, ctx); uint8_t ctxrearguard[4096]; memset(ctxfrontguard, 0xee, 4096); memset(ctxrearguard, 0xee, 4096); // break it up into pieces. byteBuffer key = hexStringToBytes(vector->keyStr); cchmac_init(di, ctx, key->len, key->bytes); ok(guard_ok(ctxfrontguard, 0xee, 4096), "context is safe"); ok(guard_ok(ctxrearguard, 0xee, 4096), "context is safe"); do { cchmac_update(di, ctx, chunk, p); total -= chunk; p += chunk; chunk /= 2; if(chunk == 0) chunk = total; } while(total); ok(guard_ok(ctxfrontguard, 0xee, 4096), "context is safe"); ok(guard_ok(ctxrearguard, 0xee, 4096), "context is safe"); cchmac_final(di, ctx, answer); ok(guard_ok(ctxfrontguard, 0xee, 4096), "context is safe"); ok(guard_ok(ctxrearguard, 0xee, 4096), "context is safe"); ok(test_answer(di, vector, answer), "check answer"); free(key); return 1; } static int test_oneshot(const struct ccdigest_info *di, test_vector *vector) { uint8_t answer[128]; byteBuffer key = hexStringToBytes(vector->keyStr); cchmac(di, key->len, key->bytes, vector->data_len, vector->data, answer); ok(test_answer(di, vector, answer), "check answer"); free(key); return 1; } static int test_hmac_many_blocks(const struct ccdigest_info *di) { static const size_t buffer_size = 16383; static uint8_t buffer[buffer_size]; static test_vector vector[] = { { keystr128, buffer, buffer_size, "7182daf0dc1007cbac6a0e719098f170", // MD2 "877a48e58590d460090c7777f4a840c6", // MD4 "7f883f92f8ef750adfa292125b9fbc55", // MD5 "4ce3f19af4a6ef30a24a178407e9fdac3b28f99a", // SHA1 "210db31bed8c58f6f79dcbce97a7cea7e2ae4a1ff5f9488b0bc45c45", // SHA224 "4185e361836f030b1e72b3f799923405741f4c9676151f496a4a0c55d3682665", // SHA256 "ae1de46bbe8045f03fa5c54a8033c9fa823bd1f244155fa479eb05f771c1f110a21d31488b40f54f710d30b2eeb23f20", // SHA384 "58b28d36a039a8267d0ad5bcef1c062caf6682699cd1ec2fa201f6d042b85946a32daee9abbeabb6ec2f29b6cadd29ce333aaa146ca1cba55302f236e03ce97d", // SHA512 "8031f9ec1222c149ca224bd90ba9eadecba75f0f", // RMD160 }, }; int vector_size = sizeof (vector) / sizeof (test_vector); for(size_t n=0; n