Home | History | Annotate | Download | only in test
      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 
    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 
    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