207 lines
8.3 KiB
C
207 lines
8.3 KiB
C
/* Copyright (c) (2012,2013,2014,2015,2016,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 (CCPBKDF2 == 0)
|
||
entryPoint(ccpbkdf2_tests,"ccpbkdf2 test")
|
||
#else
|
||
#include <corecrypto/ccasn1.h>
|
||
#include <corecrypto/ccdigest.h>
|
||
#include <corecrypto/ccdigest_priv.h>
|
||
#include <corecrypto/ccpbkdf2.h>
|
||
#include <corecrypto/ccmd2.h>
|
||
#include <corecrypto/ccmd4.h>
|
||
#include <corecrypto/ccmd5.h>
|
||
#include <corecrypto/ccsha1.h>
|
||
#include <corecrypto/ccsha2.h>
|
||
#include <corecrypto/ccripemd.h>
|
||
|
||
static const int kTestTestCount = 180;
|
||
|
||
|
||
/* Currently, ccpbkdf2 and friends won't work when length == 0 and the
|
||
* data pointer is NULL.
|
||
*/
|
||
|
||
#define password1 "password"
|
||
#define saltstr128 "000102030405060708090a0b0c0d0e0f"
|
||
|
||
|
||
#define pbkdf2_DATA_POINTER_NULL_TOLERANT 0
|
||
|
||
typedef struct test_vector_t {
|
||
char *password;
|
||
char *saltStr;
|
||
size_t iterations;
|
||
size_t result_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, size_t answer_len, 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, answer_len);
|
||
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 test_oneshot(const struct ccdigest_info *di, test_vector *vector) {
|
||
uint8_t answer[vector->result_len];
|
||
byteBuffer salt = hexStringToBytes(vector->saltStr);
|
||
ccpbkdf2_hmac(di, strlen(vector->password), vector->password, salt->len, salt->bytes, vector->iterations, vector->result_len, answer);
|
||
ok(test_answer(di, vector, vector->result_len, answer), "check answer");
|
||
free(salt);
|
||
return 1;
|
||
}
|
||
|
||
static int test_size(const struct ccdigest_info *di) {
|
||
size_t size_chk = 40;
|
||
uint8_t output_buf[size_chk];
|
||
static char *password = "test";
|
||
static const uint8_t salt[16] = {
|
||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||
};
|
||
|
||
if(sizeof(size_t) > 4) { // only valid for 64 bit.
|
||
size_t hlen = di->output_size;
|
||
size_t too_big = hlen * ((size_t) UINT32_MAX + 1);
|
||
ok(ccpbkdf2_hmac(di, strlen(password), password, sizeof(salt), salt, 10, too_big, output_buf) != 0, "Fails with size too big");
|
||
ok(ccpbkdf2_hmac(di, strlen(password), password, sizeof(salt), salt, 10, size_chk, output_buf) == 0, "Passes");
|
||
}
|
||
return 1;
|
||
|
||
}
|
||
|
||
static int test_pbkdf2(const struct ccdigest_info *di) {
|
||
static test_vector vector[] = {
|
||
{ password1, saltstr128, 100, 16,
|
||
"4fb479b7843efec99b2a9d137682bba2", // MD2
|
||
"a941b5a1246eb37e7d8bbfb803257d29", // MD4
|
||
"c21f6f8b192757dc79bfd67378255152", // MD5
|
||
"f61e774036c4007d4402fe9912e29a85", // SHA1
|
||
"78e396298731187a7e9a355694296b1f", // SHA224
|
||
"854a1e9b6834413dc51b4316dbe405e1", // SHA256
|
||
"813022dc740ec35fb4c4eaf67cd42539", // SHA384
|
||
"9842d62607fa2b5d5165d6526f74e119", // SHA512
|
||
"b68e9c0c55f521c3f2fcc84320a089de", // RMD160
|
||
},
|
||
{ password1, saltstr128, 1000, 24,
|
||
"ec806929819bb71b46b6552ac71d0e141af5360bfca0c03c", // MD2
|
||
"b8d26c6338b43b11fe2c8c7a45d31b015f72ae7cfde36778", // MD4
|
||
"cb2c261847e9e1c3141478bd084565da00024366ec9d167e", // MD5
|
||
"0309e2fe4e0bdfe7d0fe4828d41c234416e2d9bfb61cdd8f", // SHA1
|
||
"7d8603adef1af3704db8c7d2c471661ca73ac07c9044a5dc", // SHA224
|
||
"25eb86acc76e43018f18b9a8f90c2fed462d1c799e83d48a", // SHA256
|
||
"82d915ec6e30a50a987fe17cc6d260194c33fec4f2f14196", // SHA384
|
||
"c74e4080d0fbb41fee5868c0ff60fd75acae2638215987e5", // SHA512
|
||
"e4d14f220779d824d281b50a5c688a4071219411ce4ece1c", // RMD160
|
||
},
|
||
{ password1, saltstr128, 10000, 8,
|
||
"3e6698827388fc04", // MD2
|
||
"a7e2590655919ffc", // MD4
|
||
"d352d8ec8e276adc", // MD5
|
||
"8e3e2f73c3eb6390", // SHA1
|
||
"a7150cd1d2a90e2d", // SHA224
|
||
"eb6c81535592203c", // SHA256
|
||
"24f67028f09c4d89", // SHA384
|
||
"5e5984ca905a5524", // SHA512
|
||
"b35814741b948ecb", // RMD160
|
||
},
|
||
|
||
};
|
||
int vector_size = sizeof (vector) / sizeof (test_vector);
|
||
if(verbose) diag("pbkdf2 LT Test\n");
|
||
|
||
for(int i=0; i<vector_size; i++) {
|
||
ok(test_oneshot(di, &vector[i]), "test one-shot with data less than blocksize");
|
||
}
|
||
test_size(di);
|
||
return 1;
|
||
}
|
||
|
||
int ccpbkdf2_tests(TM_UNUSED int argc, TM_UNUSED char *const *argv)
|
||
{
|
||
plan_tests(kTestTestCount);
|
||
|
||
if(verbose) diag("Starting pbkdf2 tests\n");
|
||
|
||
// Pure C versions
|
||
ok(test_pbkdf2(&ccmd2_ltc_di), "ccmd2_di");
|
||
ok(test_pbkdf2(&ccmd4_ltc_di), "ccmd4_ltc_di");
|
||
ok(test_pbkdf2(&ccmd5_ltc_di), "ccmd5_ltc_di");
|
||
ok(test_pbkdf2(&ccsha1_ltc_di), "ccsha1_ltc_di");
|
||
ok(test_pbkdf2(&ccsha1_eay_di), "ccsha1_eay_di");
|
||
ok(test_pbkdf2(&ccsha224_ltc_di), "ccsha224_ltc_di");
|
||
ok(test_pbkdf2(&ccsha256_ltc_di), "ccsha256_ltc_di");
|
||
ok(test_pbkdf2(&ccsha384_ltc_di), "ccsha384_ltc_di");
|
||
ok(test_pbkdf2(&ccsha512_ltc_di), "ccsha512_ltc_di");
|
||
ok(test_pbkdf2(&ccrmd160_ltc_di), "ccrmd160_ltc_di");
|
||
|
||
// Default (optimized)
|
||
ok(test_pbkdf2(ccsha1_di()), "Default ccsha1_di");
|
||
ok(test_pbkdf2(ccsha224_di()), "Default ccsha224_di");
|
||
ok(test_pbkdf2(ccsha256_di()), "Default ccsha256_di");
|
||
ok(test_pbkdf2(ccsha384_di()), "Default ccsha384_di");
|
||
ok(test_pbkdf2(ccsha512_di()), "Default ccsha512_di");
|
||
|
||
return 0;
|
||
}
|
||
#endif
|
||
|