1/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6
7#include <stdint.h>
8#include <stdio.h>
9
10#include "cryptolib.h"
11#include "file_keys.h"
12#include "rsa_padding_test.h"
13#include "test_common.h"
14#include "utility.h"
15
16#include "2sysincludes.h"
17#include "2rsa.h"
18#include "vb2_common.h"
19
20/**
21 * Convert an old-style RSA public key struct to a new one.
22 *
23 * The new one does not allocate memory, so you must keep the old one around
24 * until you're done with the new one.
25 *
26 * @param k2		Destination new key
27 * @param key		Source old key
28 */
29void vb2_public_key_to_vb2(struct vb2_public_key *k2,
30			   const struct RSAPublicKey *key)
31{
32	k2->arrsize = key->len;
33	k2->n0inv = key->n0inv;
34	k2->n = key->n;
35	k2->rr = key->rr;
36	k2->sig_alg = vb2_crypto_to_signature(key->algorithm);
37	k2->hash_alg = vb2_crypto_to_hash(key->algorithm);
38}
39
40/**
41 * Test valid and invalid signatures.
42 */
43static void test_signatures(const struct vb2_public_key *key)
44{
45	uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES]
46		 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
47	uint8_t sig[RSA1024NUMBYTES];
48	struct vb2_workbuf wb;
49	int unexpected_success;
50	int i;
51
52	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
53
54	/* The first test signature is valid. */
55	Memcpy(sig, signatures[0], sizeof(sig));
56	TEST_SUCC(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
57		  "RSA Padding Test valid sig");
58
59	/* All other signatures should fail verification. */
60	unexpected_success = 0;
61	for (i = 1; i < sizeof(signatures) / sizeof(signatures[0]); i++) {
62		Memcpy(sig, signatures[i], sizeof(sig));
63		if (!vb2_rsa_verify_digest(key, sig,
64					   test_message_sha1_hash, &wb)) {
65			fprintf(stderr,
66				"RSA Padding Test vector %d FAILED!\n", i);
67			unexpected_success++;
68		}
69	}
70	TEST_EQ(unexpected_success, 0, "RSA Padding Test invalid sigs");
71}
72
73
74/**
75 * Test other error conditions in vb2_rsa_verify_digest().
76 */
77static void test_verify_digest(struct vb2_public_key *key) {
78	uint8_t workbuf[VB2_VERIFY_DIGEST_WORKBUF_BYTES]
79		 __attribute__ ((aligned (VB2_WORKBUF_ALIGN)));
80	uint8_t sig[RSA1024NUMBYTES];
81	struct vb2_workbuf wb;
82	enum vb2_signature_algorithm orig_key_alg = key->sig_alg;
83
84	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
85
86	Memcpy(sig, signatures[0], sizeof(sig));
87	TEST_SUCC(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
88		  "vb2_rsa_verify_digest() good");
89
90	Memcpy(sig, signatures[0], sizeof(sig));
91	vb2_workbuf_init(&wb, workbuf, sizeof(sig) * 3 - 1);
92	TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
93		VB2_ERROR_RSA_VERIFY_WORKBUF,
94		"vb2_rsa_verify_digest() small workbuf");
95	vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
96
97	key->sig_alg = VB2_SIG_INVALID;
98	Memcpy(sig, signatures[0], sizeof(sig));
99	TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
100		VB2_ERROR_RSA_VERIFY_ALGORITHM,
101		"vb2_rsa_verify_digest() bad key alg");
102	key->sig_alg = orig_key_alg;
103
104	key->arrsize *= 2;
105	Memcpy(sig, signatures[0], sizeof(sig));
106	TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
107		VB2_ERROR_RSA_VERIFY_SIG_LEN,
108		"vb2_rsa_verify_digest() bad sig len");
109	key->arrsize /= 2;
110
111	/* Corrupt the signature near start and end */
112	Memcpy(sig, signatures[0], sizeof(sig));
113	sig[3] ^= 0x42;
114	TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
115		VB2_ERROR_RSA_PADDING, "vb2_rsa_verify_digest() bad sig");
116
117	Memcpy(sig, signatures[0], sizeof(sig));
118	sig[RSA1024NUMBYTES - 3] ^= 0x56;
119	TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
120		VB2_ERROR_RSA_PADDING, "vb2_rsa_verify_digest() bad sig end");
121}
122
123int main(int argc, char *argv[])
124{
125	int error = 0;
126	RSAPublicKey *key;
127	struct vb2_public_key k2;
128
129	/* Read test key */
130	if (argc != 2) {
131		fprintf(stderr, "Usage: %s <test public key>\n", argv[0]);
132		return 1;
133	}
134	key = RSAPublicKeyFromFile(argv[1]);
135
136	if (!key) {
137		fprintf(stderr, "Couldn't read RSA public key for the test.\n");
138		return 1;
139	}
140
141	// TODO: why is test key algorithm wrong?
142	key->algorithm = 0;
143
144	/* Convert test key to Vb2 format */
145	vb2_public_key_to_vb2(&k2, key);
146
147	/* Run tests */
148	test_signatures(&k2);
149	test_verify_digest(&k2);
150
151	/* Clean up and exit */
152	RSAPublicKeyFree(key);
153
154	if (!gTestSuccess)
155		error = 255;
156
157	return error;
158}
159