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  */
vb2_public_key_to_vb2(struct vb2_public_key * k2,const struct RSAPublicKey * key)29 void 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  */
test_signatures(const struct vb2_public_key * key)43 static 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  */
test_verify_digest(struct vb2_public_key * key)77 static 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 
main(int argc,char * argv[])123 int 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