summaryrefslogtreecommitdiff
path: root/test/u2f.c
blob: c74bc847a342954724237d41ca2482e36ff4e9f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Copyright 2021 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "test_util.h"
#include "u2f_impl.h"

/******************************************************************************/
/* Mock implementations of cr50 board.
 */
int system_get_chip_unique_id(uint8_t **id)
{
	return P256_NBYTES;
}

/******************************************************************************/
/* Mock implementations of Dcrypto functionality.
 */
int DCRYPTO_ladder_random(void *output)
{
	memset(output, 0, P256_NBYTES);
	/* Return 1 for success, 0 for error. */
	return 1;
}

int DCRYPTO_x509_gen_u2f_cert_name(const p256_int *d, const p256_int *pk_x,
				   const p256_int *pk_y, const p256_int *serial,
				   const char *name, uint8_t *cert,
				   const int n)
{
	/* Return the size of certificate, 0 means error. */
	return 0;
}

int dcrypto_p256_ecdsa_sign(struct drbg_ctx *drbg, const p256_int *key,
			    const p256_int *message, p256_int *r, p256_int *s)
{
	memset(r, 0, sizeof(p256_int));
	memset(s, 0, sizeof(p256_int));
	/* Return 1 for success, 0 for error. */
	return 1;
}

/******************************************************************************/
/* Mock implementations of U2F functionality.
 */
static int presence;

static struct u2f_state state;

struct u2f_state *get_state(void)
{
	return &state;
}

enum touch_state pop_check_presence(int consume)
{
	enum touch_state ret = presence ?
		POP_TOUCH_YES : POP_TOUCH_NO;

	if (consume)
		presence = 0;
	return ret;
}

int u2f_origin_user_keypair(const uint8_t *key_handle, size_t key_handle_size,
			    p256_int *d, p256_int *pk_x, p256_int *pk_y)
{
	return EC_SUCCESS;
}

int g2f_individual_keypair(p256_int *d, p256_int *pk_x, p256_int *pk_y)
{
	return EC_SUCCESS;
}

/******************************************************************************/
/* Tests begin here.
 */
static uint8_t buffer[512];

test_static int test_u2f_generate_no_require_presence(void)
{
	struct u2f_generate_req *req = (struct u2f_generate_req *)buffer;
	size_t response_size = sizeof(struct u2f_generate_resp);
	int ret;

	memset(buffer, 0, sizeof(buffer));
	req->flags = 0;
	presence = 0;
	ret = u2f_generate(
		VENDOR_CC_U2F_GENERATE, &buffer,
		sizeof(struct u2f_generate_req),
		&response_size);

	TEST_ASSERT(ret == VENDOR_RC_SUCCESS);
	return EC_SUCCESS;
}

test_static int test_u2f_generate_require_presence(void)
{
	struct u2f_generate_req *req = (struct u2f_generate_req *)buffer;
	size_t response_size = sizeof(struct u2f_generate_resp);
	int ret;

	memset(buffer, 0, sizeof(buffer));
	req->flags = U2F_AUTH_FLAG_TUP;
	presence = 0;
	ret = u2f_generate(
		VENDOR_CC_U2F_GENERATE, &buffer,
		sizeof(struct u2f_generate_req),
		&response_size);
	TEST_ASSERT(ret == VENDOR_RC_NOT_ALLOWED);

	memset(buffer, 0, sizeof(buffer));
	req->flags = U2F_AUTH_FLAG_TUP;
	response_size = sizeof(struct u2f_generate_resp);
	presence = 1;
	ret = u2f_generate(
		VENDOR_CC_U2F_GENERATE, &buffer,
		sizeof(struct u2f_generate_req),
		&response_size);
	TEST_ASSERT(ret == VENDOR_RC_SUCCESS);

	return EC_SUCCESS;
}

void run_test(void)
{
	RUN_TEST(test_u2f_generate_no_require_presence);
	RUN_TEST(test_u2f_generate_require_presence);

	test_print_result();
}