blob: b5a7b3a36b36c93fad321b871504257d94a490e0 [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
27#include <stdio.h>
28#include <ctype.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "mincrypt/p256.h"
33#include "mincrypt/p256_ecdsa.h"
34#include "mincrypt/sha256.h"
35
36/**
37 * Messages signed using:
38 *
39-----BEGIN EC PRIVATE KEY-----
40MHcCAQEEIDw6UiziVMbjlfSpOAIpA2tcL+v1OlznZLnpadO8BGi1oAoGCCqGSM49
41AwEHoUQDQgAEZw7VAOjAXYRFuhZWYBgjahdOvkwcAnjGkxQWytZW+iS1hI3ZGE24
426XmNka9IGxAgj2n/ip+MuZJMFoJ9DRea3g==
43-----END EC PRIVATE KEY-----
44 */
45
46p256_int key_x = {
47 .a = {0xd656fa24u, 0x931416cau, 0x1c0278c6u, 0x174ebe4cu,
48 0x6018236au, 0x45ba1656u, 0xe8c05d84u, 0x670ed500u}
49};
50p256_int key_y = {
51 .a = {0x0d179adeu, 0x4c16827du, 0x9f8cb992u, 0x8f69ff8au,
52 0x481b1020u, 0x798d91afu, 0x184db8e9u, 0xb5848dd9u}
53};
54
55char* message_1 =
56 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
57 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
58 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
59 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
60 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
61 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
62 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
63 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
64 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
65 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
66 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
67 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
68 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
69 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
70 "d5 9d 73 be 12";
71
72char* signature_1 =
73 "30 44 02 20 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
74 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
75 "7c 98 25 d9 02 20 54 f3 7f 5a e9 36 9c a2 f0 51"
76 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
77 "ea 57 7e 88 46 12";
78
79// Same as signature 1, but with leading zeroes.
80char* message_2 =
81 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
82 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
83 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
84 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
85 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
86 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
87 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
88 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
89 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
90 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
91 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
92 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
93 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
94 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
95 "d5 9d 73 be 12";
96
97char* signature_2 =
98 "30 46 02 21 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
99 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
100 "7c 98 25 d9 02 21 00 54 f3 7f 5a e9 36 9c a2 f0 51"
101 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
102 "ea 57 7e 88 46 12";
103
104// Excessive zeroes on the signature
105char* message_3 =
106 "f4 5d 55 f3 55 51 e9 75 d6 a8 dc 7e a9 f4 88 59"
107 "39 40 cc 75 69 4a 27 8f 27 e5 78 a1 63 d8 39 b3"
108 "40 40 84 18 08 cf 9c 58 c9 b8 72 8b f5 f9 ce 8e"
109 "e8 11 ea 91 71 4f 47 ba b9 2d 0f 6d 5a 26 fc fe"
110 "ea 6c d9 3b 91 0c 0a 2c 96 3e 64 eb 18 23 f1 02"
111 "75 3d 41 f0 33 59 10 ad 3a 97 71 04 f1 aa f6 c3"
112 "74 27 16 a9 75 5d 11 b8 ee d6 90 47 7f 44 5c 5d"
113 "27 20 8b 2e 28 43 30 fa 3d 30 14 23 fa 7f 2d 08"
114 "6e 0a d0 b8 92 b9 db 54 4e 45 6d 3f 0d ab 85 d9"
115 "53 c1 2d 34 0a a8 73 ed a7 27 c8 a6 49 db 7f a6"
116 "37 40 e2 5e 9a f1 53 3b 30 7e 61 32 99 93 11 0e"
117 "95 19 4e 03 93 99 c3 82 4d 24 c5 1f 22 b2 6b de"
118 "10 24 cd 39 59 58 a2 df eb 48 16 a6 e8 ad ed b5"
119 "0b 1f 6b 56 d0 b3 06 0f f0 f1 c4 cb 0d 0e 00 1d"
120 "d5 9d 73 be 12";
121
122char* signature_3 =
123 "30 4c 02 24 00 00 00 00 43 18 fc eb 3b a8 3a a8 a3 cf 41 b7"
124 "81 4a f9 01 e1 8b 6e 95 c1 3a 83 25 9e a5 2e 66"
125 "7c 98 25 d9 02 24 00 00 00 00 54 f3 7f 5a e9 36 9c a2 f0 51"
126 "e0 6e 78 48 60 a3 f9 8a d5 2c 37 5a 0a 29 c9 f7"
127 "ea 57 7e 88 46 12";
128
129
130char* good_dsa_signature_1 =
131 "30 0D 02 01 01 02 08 00 A5 55 5A 01 FF A5 01";
132p256_int good_dsa_signature_1_r = {
133 .a = {0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U,
134 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
135};
136p256_int good_dsa_signature_1_s = {
137 .a = {0x01FFA501U, 0x00A5555AU, 0x00000000U, 0x00000000U,
138 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
139};
140
141
142char* bad_dsa_signature_1 =
143 "a0 06 02 01 01 02 01 01";
144
145char* bad_dsa_signature_2 =
146 "30 07 02 01 01 02 01 01";
147
148char* bad_dsa_signature_3 =
149 "30 06 82 01 01 02 01 01";
150
151char* bad_dsa_signature_4 =
152 "30 06 02 00 01 02 01 01";
153
154char* bad_dsa_signature_5 =
155 "30 06 02 01 01 82 01 01";
156
157char* bad_dsa_signature_6 =
158 "30 05 02 01 01 02 00";
159
160char* bad_dsa_signature_7 =
161 "30 06 02 01 01 02 00 01";
162
163unsigned char* parsehex(char* str, int* len) {
164 // result can't be longer than input
165 unsigned char* result = malloc(strlen(str));
166
167 unsigned char* p = result;
168 *len = 0;
169
170 while (*str) {
171 int b;
172
173 while (isspace(*str)) str++;
174
175 switch (*str) {
176 case '0': case '1': case '2': case '3': case '4':
177 case '5': case '6': case '7': case '8': case '9':
178 b = (*str - '0') << 4; break;
179 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
180 b = (*str - 'a' + 10) << 4; break;
181 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
182 b = (*str - 'A' + 10) << 4; break;
183 case '\0':
184 return result;
185 default:
186 return NULL;
187 }
188 str++;
189
190 while (isspace(*str)) str++;
191
192 switch (*str) {
193 case '0': case '1': case '2': case '3': case '4':
194 case '5': case '6': case '7': case '8': case '9':
195 b |= *str - '0'; break;
196 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
197 b |= *str - 'a' + 10; break;
198 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
199 b |= *str - 'A' + 10; break;
200 default:
201 return NULL;
202 }
203 str++;
204
205 *p++ = b;
206 ++*len;
207 }
208
209 return result;
210}
211
212int main(int arg, char** argv) {
213
214 unsigned char hash_buf[SHA256_DIGEST_SIZE];
215
216 unsigned char* message;
217 int mlen;
218 unsigned char* signature;
219 int slen;
220
221 p256_int hash;
222 p256_int r;
223 p256_int s;
224
225 int success = 1;
226
227#define CHECK_DSA_SIG(sig, good) do {\
228 message = parsehex(sig, &mlen); \
229 int result = dsa_sig_unpack(message, mlen, &r, &s); \
230 printf(#sig ": %s\n", result ? "good" : "bad"); \
231 success = success && !(good ^ result); \
232 free(message); \
233 } while(0)
234#define CHECK_GOOD_DSA_SIG(n) do {\
235 CHECK_DSA_SIG(good_dsa_signature_##n, 1); \
236 int result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_r), P256_DIGITS(&r), \
237 P256_NBYTES); \
238 success = success && result; \
239 printf(" R value %s\n", result ? "good" : "bad"); \
240 result = !memcmp(P256_DIGITS(&good_dsa_signature_##n##_s), P256_DIGITS(&s), \
241 P256_NBYTES); \
242 success = success && result; \
243 printf(" S value %s\n", result ? "good" : "bad"); \
244 } while (0)
245#define CHECK_BAD_DSA_SIG(n) \
246 CHECK_DSA_SIG(bad_dsa_signature_##n, 0)
247
248 CHECK_GOOD_DSA_SIG(1);
249
250 CHECK_BAD_DSA_SIG(1);
251 CHECK_BAD_DSA_SIG(2);
252 CHECK_BAD_DSA_SIG(3);
253 CHECK_BAD_DSA_SIG(4);
254 CHECK_BAD_DSA_SIG(5);
255 CHECK_BAD_DSA_SIG(6);
256 CHECK_BAD_DSA_SIG(7);
257
258
259#define TEST_MESSAGE(n) do {\
260 message = parsehex(message_##n, &mlen); \
261 SHA256_hash(message, mlen, hash_buf); \
262 p256_from_bin(hash_buf, &hash); \
263 signature = parsehex(signature_##n, &slen); \
264 int result = dsa_sig_unpack(signature, slen, &r, &s); \
265 if (result) { result = p256_ecdsa_verify(&key_x, &key_y, &hash, &r, &s); } \
266 printf("message %d: %s\n", n, result ? "verified" : "not verified"); \
267 success = success && result; \
268 free(signature); \
269 } while(0)
270
271 TEST_MESSAGE(1);
272 TEST_MESSAGE(2);
273 TEST_MESSAGE(3);
274
275 printf("\n%s\n\n", success ? "PASS" : "FAIL");
276
277 return !success;
278}