1 /*
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 <ctype.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/cdefs.h>
32 
33 #include "constrainedcrypto/dsa_sig.h"
34 #include "constrainedcrypto/p256.h"
35 #include "constrainedcrypto/p256_ecdsa.h"
36 #include "constrainedcrypto/sha256.h"
37 
38 #ifndef __unused
39 #define __unused __attribute__((__unused__))
40 #endif
41 
42 /**
43  * Messages signed using:
44  *
45 -----BEGIN EC PRIVATE KEY-----
46 MHcCAQEEIDw6UiziVMbjlfSpOAIpA2tcL+v1OlznZLnpadO8BGi1oAoGCCqGSM49
47 AwEHoUQDQgAEZw7VAOjAXYRFuhZWYBgjahdOvkwcAnjGkxQWytZW+iS1hI3ZGE24
48 6XmNka9IGxAgj2n/ip+MuZJMFoJ9DRea3g==
49 -----END EC PRIVATE KEY-----
50  */
51 
52 p256_int key_x = {
53     .a = {0xd656fa24u, 0x931416cau, 0x1c0278c6u, 0x174ebe4cu,
54           0x6018236au, 0x45ba1656u, 0xe8c05d84u, 0x670ed500u}
55 };
56 p256_int key_y = {
57     .a = {0x0d179adeu, 0x4c16827du, 0x9f8cb992u, 0x8f69ff8au,
58           0x481b1020u, 0x798d91afu, 0x184db8e9u, 0xb5848dd9u}
59 };
60 
61 char* 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 
78 char* 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.
86 char* 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 
103 char* 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
111 char* 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 
128 char* 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 
136 char* good_dsa_signature_1 =
137     "30 0D 02 01 01 02 08 00 A5 55 5A 01 FF A5 01";
138 p256_int good_dsa_signature_1_r = {
139     .a = {0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U,
140           0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
141 };
142 p256_int good_dsa_signature_1_s = {
143     .a = {0x01FFA501U, 0x00A5555AU, 0x00000000U, 0x00000000U,
144           0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U}
145 };
146 
147 
148 char* bad_dsa_signature_1 =
149      "a0 06 02 01 01 02 01 01";
150 
151 char* bad_dsa_signature_2 =
152      "30 07 02 01 01 02 01 01";
153 
154 char* bad_dsa_signature_3 =
155      "30 06 82 01 01 02 01 01";
156 
157 char* bad_dsa_signature_4 =
158      "30 06 02 00 01 02 01 01";
159 
160 char* bad_dsa_signature_5 =
161      "30 06 02 01 01 82 01 01";
162 
163 char* bad_dsa_signature_6 =
164      "30 05 02 01 01 02 00";
165 
166 char* bad_dsa_signature_7 =
167      "30 06 02 01 01 02 00 01";
168 
parsehex(char * str,int * len)169 unsigned 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 
main(int arg __unused,char ** argv __unused)218 int main(int arg __unused, char** argv __unused) {
219 
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 }
285