corecrypto/ccsrp/crypto_test/ccsrptest.c

302 lines
11 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) (2012,2013,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"
#if (CCSRP == 0)
entryPoint(ccsrp_tests, "ccsrp test")
#else
#include <corecrypto/ccsrp.h>
#include <corecrypto/ccsrp_gp.h>
#include <corecrypto/ccsha1.h>
#include <corecrypto/ccsha2.h>
struct ccsrp_vector {
const struct ccdigest_info *(*di)(void);
ccdh_const_gp_t (*gp)(void);
uint32_t opt;
const char *U;
const char *P;
const char *salt;
const char *k;
const char *x;
const char *v;
const char *a;
const char *b;
const char *A;
const char *B;
const char *u;
const char *S;
const char *K;
const char *M;
const char *HAMK;
};
struct ccsrp_option {
uint32_t v;
const char *string;
};
const struct ccsrp_vector ccsrp_vectors[] = {
#include "../test_vectors/srp.inc"
};
/*
Appendix B. SRP Test Vectors
The following test vectors demonstrate calculation of the verifier
and premaster secret.
*/
static int srp_test_vector(const struct ccsrp_vector *test, struct ccrng_state *rng)
{
int rc = -1;
const struct ccdigest_info *di = test->di();
ccsrp_const_gp_t gp = test->gp();
const char *I = test->U;
const char *P = test->P;
byteBuffer salt = hexStringToBytes(test->salt);
byteBuffer k = hexStringToBytes(test->k);
byteBuffer x = hexStringToBytes(test->x);
byteBuffer v = hexStringToBytes(test->v);
byteBuffer a = hexStringToBytes(test->a);
byteBuffer b = hexStringToBytes(test->b);
byteBuffer A = hexStringToBytes(test->A);
byteBuffer B = hexStringToBytes(test->B);
byteBuffer u = hexStringToBytes(test->u);
byteBuffer S = hexStringToBytes(test->S);
byteBuffer K = hexStringToBytes(test->K);
byteBuffer M = hexStringToBytes(test->M);
byteBuffer HAMK = hexStringToBytes(test->HAMK);
rc = ccsrp_test_calculations(di,
gp,
rng,
I,
test->opt,
strlen(P),
P,
salt->len,
salt->bytes,
k->len,
k->bytes,
x->len,
x->bytes,
v->len,
v->bytes,
a->len,
a->bytes,
b->len,
b->bytes,
A->len,
A->bytes,
B->len,
B->bytes,
u->len,
u->bytes,
S->len,
S->bytes,
K->len,
K->bytes,
M->len,
M->bytes,
HAMK->len,
HAMK->bytes);
free(salt);
free(k);
free(x);
free(u);
free(v);
free(a);
free(b);
free(A);
free(B);
free(S);
free(K);
free(M);
free(HAMK);
return rc;
}
static int verbose = 0;
#define NITER 100
#define TEST_HASH SRP_SHA1
#define TEST_NG SRP_NG_1024
#define SRP_TEST_MAX_SESSION_KEY_LENGTH 96
static int test_srp(const struct ccdigest_info *di,
ccsrp_const_gp_t gp,
struct ccrng_state *rng,
uint32_t option)
{
ccsrp_ctx_decl(di, gp, client_srp);
ccsrp_ctx_decl(di, gp, server_srp);
ccsrp_ctx_init_option(client_srp, di, gp, option, rng);
ccsrp_ctx_init_option(server_srp, di, gp, option, rng);
size_t pki_size = ccsrp_ctx_sizeof_n(client_srp);
const char *username = "testuser";
const char *password = "password";
uint8_t salt[64];
uint8_t verifier[pki_size];
uint8_t A[pki_size];
uint8_t B[pki_size];
uint8_t M[ccsrp_ctx_M_HAMK_size(client_srp)];
uint8_t bytes_HAMK[ccsrp_ctx_M_HAMK_size(client_srp)];
size_t client_session_key_length = SRP_TEST_MAX_SESSION_KEY_LENGTH;
size_t server_session_key_length = SRP_TEST_MAX_SESSION_KEY_LENGTH;
size_t salt_len, password_len;
salt_len = 64;
password_len = strlen(password);
if (verbose)
diag("test_srp.0\n");
ok_or_fail(ccsrp_generate_salt_and_verification(
client_srp, rng, username, password_len, password, salt_len, salt, verifier) ==
0,
"Generate Salt and Verifier");
// Generate a and A
if (verbose)
diag("test_srp.2\n");
ok_or_fail(ccsrp_client_start_authentication(client_srp, rng, A) == 0,
"Start client authentication");
// Client sends A to server
// Generate b and B using A
if (verbose)
diag("test_srp.3\n");
ok_or_fail(ccsrp_server_start_authentication(
server_srp, rng, username, salt_len, salt, verifier, A, B) == 0,
"Verifier SRP-6a safety check");
// Client uses s and B to generate M to answer challenge
if (verbose)
diag("test_srp.4\n");
ok_or_fail(ccsrp_client_process_challenge(
client_srp, username, password_len, password, salt_len, salt, B, M) == 0,
"User SRP-6a safety check");
// Verify session key.
const void *ck = ccsrp_get_session_key(client_srp, &client_session_key_length);
const void *sk = ccsrp_get_session_key(server_srp, &server_session_key_length);
ok(ck && sk &&
ccsrp_get_session_key_length(client_srp) == ccsrp_get_session_key_length(server_srp) &&
ccsrp_get_session_key_length(client_srp) == client_session_key_length &&
ccsrp_get_session_key_length(server_srp) == server_session_key_length &&
memcmp(ck, sk, ccsrp_get_session_key_length(client_srp)) == 0,
"Session Keys don't match");
// Verify M was generated correctly - generate HAMK
if (verbose)
diag("test_srp.5\n");
ok_or_fail(ccsrp_server_verify_session(server_srp, M, bytes_HAMK), "User authentication");
// Client verifies correct HAMK
if (verbose)
diag("test_srp.6\n");
ok_or_fail(ccsrp_client_verify_session(client_srp, bytes_HAMK), "Server Authentication");
if (verbose)
diag("test_srp.7\n");
ok(ccsrp_is_authenticated(client_srp), "Server Authentication");
ccsrp_ctx_clear(di, gp, client_srp);
ccsrp_ctx_clear(di, gp, server_srp);
return 1;
}
#define SRP_OPTION_TEST(t) \
{ \
t, #t \
}
int ccsrp_tests(TM_UNUSED int argc, TM_UNUSED char *const *argv)
{
struct ccrng_state *rng = global_test_rng;
struct ccsrp_option test_options[] = { SRP_OPTION_TEST(CCSRP_OPTION_SRP6a_HASH),
SRP_OPTION_TEST(CCSRP_OPTION_SRP6a_MGF1),
SRP_OPTION_TEST(CCSRP_OPTION_RFC2945_INTERLEAVED) };
plan_tests(15 + 3 * 5 * 5 * (8 + 1));
for (size_t i = 0; i < sizeof(ccsrp_vectors) / sizeof(ccsrp_vectors[0]); i++) {
diag("SRP KAT Test %d", i);
ok(srp_test_vector(&ccsrp_vectors[i], rng) == 0, "SRP KAT Test");
}
for (size_t i = 0; i < sizeof(test_options) / sizeof(test_options[0]); i++) {
diag("SRP 1024 tests (%s)", test_options[i].string);
ok(test_srp(ccsha1_di(), ccsrp_gp_rfc5054_1024(), rng, test_options[i].v), "SHA1/GP1024");
ok(test_srp(ccsha224_di(), ccsrp_gp_rfc5054_1024(), rng, test_options[i].v),
"SHA224/GP1024");
ok(test_srp(ccsha256_di(), ccsrp_gp_rfc5054_1024(), rng, test_options[i].v),
"SHA256/GP1024");
ok(test_srp(ccsha384_di(), ccsrp_gp_rfc5054_1024(), rng, test_options[i].v),
"SHA384/GP1024");
ok(test_srp(ccsha512_di(), ccsrp_gp_rfc5054_1024(), rng, test_options[i].v),
"SHA512/GP1024");
diag("SRP 2048 tests (%s)", test_options[i].string);
ok(test_srp(ccsha1_di(), ccsrp_gp_rfc5054_2048(), rng, test_options[i].v), "SHA1/GP2048");
ok(test_srp(ccsha224_di(), ccsrp_gp_rfc5054_2048(), rng, test_options[i].v),
"SHA224/GP2048");
ok(test_srp(ccsha256_di(), ccsrp_gp_rfc5054_2048(), rng, test_options[i].v),
"SHA256/GP2048");
ok(test_srp(ccsha384_di(), ccsrp_gp_rfc5054_2048(), rng, test_options[i].v),
"SHA384/GP2048");
ok(test_srp(ccsha512_di(), ccsrp_gp_rfc5054_2048(), rng, test_options[i].v),
"SHA512/GP2048");
#if CORECRYPTO_HACK_FOR_WINDOWS_DEVELOPMENT
diag("*skipping tests on Windows");
#else
diag("SRP 3072 tests (%s)", test_options[i].string);
ok(test_srp(ccsha1_di(), ccsrp_gp_rfc5054_3072(), rng, test_options[i].v), "SHA1/GP3072");
ok(test_srp(ccsha224_di(), ccsrp_gp_rfc5054_3072(), rng, test_options[i].v),
"SHA224/GP3072");
ok(test_srp(ccsha256_di(), ccsrp_gp_rfc5054_3072(), rng, test_options[i].v),
"SHA256/GP3072");
ok(test_srp(ccsha384_di(), ccsrp_gp_rfc5054_3072(), rng, test_options[i].v),
"SHA384/GP3072");
ok(test_srp(ccsha512_di(), ccsrp_gp_rfc5054_3072(), rng, test_options[i].v),
"SHA512/GP3072");
diag("SRP 4096 tests (%s)", test_options[i].string);
ok(test_srp(ccsha1_di(), ccsrp_gp_rfc5054_4096(), rng, test_options[i].v), "SHA1/GP4096");
ok(test_srp(ccsha224_di(), ccsrp_gp_rfc5054_4096(), rng, test_options[i].v),
"SHA224/GP4096");
ok(test_srp(ccsha256_di(), ccsrp_gp_rfc5054_4096(), rng, test_options[i].v),
"SHA256/GP4096");
ok(test_srp(ccsha384_di(), ccsrp_gp_rfc5054_4096(), rng, test_options[i].v),
"SHA384/GP4096");
ok(test_srp(ccsha512_di(), ccsrp_gp_rfc5054_4096(), rng, test_options[i].v),
"SHA512/GP4096");
diag("SRP 8192 tests (%s)", test_options[i].string);
ok(test_srp(ccsha1_di(), ccsrp_gp_rfc5054_8192(), rng, test_options[i].v), "SHA1/GP8192");
ok(test_srp(ccsha224_di(), ccsrp_gp_rfc5054_8192(), rng, test_options[i].v),
"SHA224/GP8192");
ok(test_srp(ccsha256_di(), ccsrp_gp_rfc5054_8192(), rng, test_options[i].v),
"SHA256/GP8192");
ok(test_srp(ccsha384_di(), ccsrp_gp_rfc5054_8192(), rng, test_options[i].v),
"SHA384/GP8192");
ok(test_srp(ccsha512_di(), ccsrp_gp_rfc5054_8192(), rng, test_options[i].v),
"SHA512/GP8192");
#endif
}
return 0;
}
#endif