blob: 24ec0131fc7670df7335051d1b0dad08db223341 [file] [log] [blame]
Kenny Rootdb0850c2013-10-08 12:52:07 -07001/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Google Inc. nor the names of its contributors may
12 * be used to endorse or promote products derived from this software
13 * without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
Kenny Rootdb0850c2013-10-08 12:52:07 -070027#include <ctype.h>
Mark Salyzynf03f8482014-04-30 14:12:23 -070028#include <stdio.h>
Kenny Rootdb0850c2013-10-08 12:52:07 -070029#include <stdlib.h>
30#include <string.h>
Mark Salyzynf03f8482014-04-30 14:12:23 -070031#include <sys/cdefs.h>
Kenny Rootdb0850c2013-10-08 12:52:07 -070032
Mark Salyzynf03f8482014-04-30 14:12:23 -070033#include "mincrypt/dsa_sig.h"
Kenny Rootdb0850c2013-10-08 12:52:07 -070034#include "mincrypt/p256.h"
35#include "mincrypt/p256_ecdsa.h"
36#include "mincrypt/sha256.h"
37
Mark Salyzynf03f8482014-04-30 14:12:23 -070038#ifndef __unused
39#define __unused __attribute__((__unused__))
40#endif
41
Kenny Rootdb0850c2013-10-08 12:52:07 -070042/**
43 * Messages signed using:
44 *
45-----BEGIN EC PRIVATE KEY-----
46MHcCAQEEIDw6UiziVMbjlfSpOAIpA2tcL+v1OlznZLnpadO8BGi1oAoGCCqGSM49
47AwEHoUQDQgAEZw7VAOjAXYRFuhZWYBgjahdOvkwcAnjGkxQWytZW+iS1hI3ZGE24
486XmNka9IGxAgj2n/ip+MuZJMFoJ9DRea3g==
49-----END EC PRIVATE KEY-----
50 */
51
52p256_int key_x = {
53 .a = {0xd656fa24u, 0x931416cau, 0x1c0278c6u, 0x174ebe4cu,
54 0x6018236au, 0x45ba1656u, 0xe8c05d84u, 0x670ed500u}
55};
56p256_int key_y = {
57 .a = {0x0d179adeu, 0x4c16827du, 0x9f8cb992u, 0x8f69ff8au,
58 0x481b1020u, 0x798d91afu, 0x184db8e9u, 0xb5848dd9u}
59};
60
61char* message_1 =
62 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
63 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
64 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
65 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
66 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
67 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
68 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
69 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
70 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
71 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
72 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
73 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
74 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
75 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
76 "d5 9d 73 be 12";
77
78char* signature_1 =
79 "30 44 02 20 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
80 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
81 "7c 98 25 d9 02 20 54 f3 7f 5a e9 36 9c a2 f0 51"
82 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
83 "ea 57 7e 88 46 12";
84
85// Same as signature 1, but with leading zeroes.
86char* message_2 =
87 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
88 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
89 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
90 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
91 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
92 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
93 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
94 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
95 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
96 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
97 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
98 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
99 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
100 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
101 "d5 9d 73 be 12";
102
103char* signature_2 =
104 "30 46 02 21 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
105 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
106 "7c 98 25 d9 02 21 00 54 f3 7f 5a e9 36 9c a2 f0 51"
107 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
108 "ea 57 7e 88 46 12";
109
110// Excessive zeroes on the signature
111char* message_3 =
112 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
113 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
114 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
115 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
116 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
117 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
118 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
119 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
120 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
121 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
122 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
123 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
124 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
125 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
126 "d5 9d 73 be 12";
127
128char* signature_3 =
129 "30 4c 02 24 00 00 00 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
130 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
131 "7c 98 25 d9 02 24 00 00 00 00 54 f3 7f 5a e9 36 9c a2 f0 51"
132 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
133 "ea 57 7e 88 46 12";
134
135
136char* good_dsa_signature_1 =
137 "30 0D 02 01 01 02 08 00 A5 55 5A 01 FF A5 01";
138p256_int good_dsa_signature_1_r = {
139 .a = {0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U,
140 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
141};
142p256_int good_dsa_signature_1_s = {
143 .a = {0x01FFA501U, 0x00A5555AU, 0x00000000U, 0x00000000U,
144 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
145};
146
147
148char* bad_dsa_signature_1 =
149 "a0 06 02 01 01 02 01 01";
150
151char* bad_dsa_signature_2 =
152 "30 07 02 01 01 02 01 01";
153
154char* bad_dsa_signature_3 =
155 "30 06 82 01 01 02 01 01";
156
157char* bad_dsa_signature_4 =
158 "30 06 02 00 01 02 01 01";
159
160char* bad_dsa_signature_5 =
161 "30 06 02 01 01 82 01 01";
162
163char* bad_dsa_signature_6 =
164 "30 05 02 01 01 02 00";
165
166char* bad_dsa_signature_7 =
167 "30 06 02 01 01 02 00 01";
168
169unsigned char* parsehex(char* str, int* len) {
170 // result can't be longer than input
171 unsigned char* result = malloc(strlen(str));
172
173 unsigned char* p = result;
174 *len = 0;
175
176 while (*str) {
177 int b;
178
179 while (isspace(*str)) str++;
180
181 switch (*str) {
182 case '0': case '1': case '2': case '3': case '4':
183 case '5': case '6': case '7': case '8': case '9':
184 b = (*str - '0') << 4; break;
185 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
186 b = (*str - 'a' + 10) << 4; break;
187 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
188 b = (*str - 'A' + 10) << 4; break;
189 case '\0':
190 return result;
191 default:
192 return NULL;
193 }
194 str++;
195
196 while (isspace(*str)) str++;
197
198 switch (*str) {
199 case '0': case '1': case '2': case '3': case '4':
200 case '5': case '6': case '7': case '8': case '9':
201 b |= *str - '0'; break;
202 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
203 b |= *str - 'a' + 10; break;
204 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
205 b |= *str - 'A' + 10; break;
206 default:
207 return NULL;
208 }
209 str++;
210
211 *p++ = b;
212 ++*len;
213 }
214
215 return result;
216}
217
Mark Salyzynf03f8482014-04-30 14:12:23 -0700218int main(int arg __unused, char** argv __unused) {
Kenny Rootdb0850c2013-10-08 12:52:07 -0700219
220 unsigned char hash_buf[SHA256_DIGEST_SIZE];
221
222 unsigned char* message;
223 int mlen;
224 unsigned char* signature;
225 int slen;
226
227 p256_int hash;
228 p256_int r;
229 p256_int s;
230
231 int success = 1;
232
233#define CHECK_DSA_SIG(sig, good) do {\
234 message = parsehex(sig, &mlen); \
235 int result = dsa_sig_unpack(message, mlen, &r, &s); \
236 printf(#sig ": %s\n", result ? "good" : "bad"); \
237 success = success && !(good ^ result); \
238 free(message); \
239 } while(0)
240#define CHECK_GOOD_DSA_SIG(n) do {\
241 CHECK_DSA_SIG(good_dsa_signature_##n, 1); \
242 int result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_r), P256_DIGITS(&r), \
243 P256_NBYTES); \
244 success = success && result; \
245 printf(" R value %s\n", result ? "good" : "bad"); \
246 result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_s), P256_DIGITS(&s), \
247 P256_NBYTES); \
248 success = success && result; \
249 printf(" S value %s\n", result ? "good" : "bad"); \
250 } while (0)
251#define CHECK_BAD_DSA_SIG(n) \
252 CHECK_DSA_SIG(bad_dsa_signature_##n, 0)
253
254 CHECK_GOOD_DSA_SIG(1);
255
256 CHECK_BAD_DSA_SIG(1);
257 CHECK_BAD_DSA_SIG(2);
258 CHECK_BAD_DSA_SIG(3);
259 CHECK_BAD_DSA_SIG(4);
260 CHECK_BAD_DSA_SIG(5);
261 CHECK_BAD_DSA_SIG(6);
262 CHECK_BAD_DSA_SIG(7);
263
264
265#define TEST_MESSAGE(n) do {\
266 message = parsehex(message_##n, &mlen); \
267 SHA256_hash(message, mlen, hash_buf); \
268 p256_from_bin(hash_buf, &hash); \
269 signature = parsehex(signature_##n, &slen); \
270 int result = dsa_sig_unpack(signature, slen, &r, &s); \
271 if (result) { result = p256_ecdsa_verify(&key_x, &key_y, &hash, &r, &s); } \
272 printf("message %d: %s\n", n, result ? "verified" : "not verified"); \
273 success = success && result; \
274 free(signature); \
275 } while(0)
276
277 TEST_MESSAGE(1);
278 TEST_MESSAGE(2);
279 TEST_MESSAGE(3);
280
281 printf("\n%s\n\n", success ? "PASS" : "FAIL");
282
283 return !success;
284}