1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include <tomcrypt_test.h>
10 
11 #if defined(LTC_MDSA) && defined(LTC_TEST_MPI)
12 
13 /* This is the private key from test_dsa.key */
14 static const unsigned char openssl_priv_dsa[] = {
15   0x30, 0x82, 0x01, 0xbb, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc5,
16   0x0a, 0x37, 0x51, 0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70, 0xbd, 0x4a,
17   0x6f, 0x6b, 0x4a, 0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99, 0x38, 0x7d,
18   0x9a, 0x64, 0xd6, 0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac, 0xa8, 0xac,
19   0xc6, 0x1b, 0x65, 0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a, 0x18, 0x2c,
20   0xee, 0xa1, 0x07, 0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90, 0xc7, 0x03,
21   0x21, 0xfa, 0x09, 0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb, 0xfd, 0xbf,
22   0xb3, 0xef, 0xad, 0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06, 0x92, 0x4a,
23   0x85, 0x2a, 0xff, 0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6, 0x67, 0x41,
24   0x84, 0x5a, 0xc0, 0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62, 0x05, 0xa4,
25   0xfa, 0x48, 0xa0, 0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe, 0xb9, 0x81,
26   0xab, 0xee, 0xbe, 0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00, 0xaa, 0x5b,
27   0xd7, 0xf4, 0xe5, 0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca, 0x00, 0xc7,
28   0xa6, 0x35, 0x71, 0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b, 0x92, 0xe4,
29   0xff, 0x59, 0x29, 0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2, 0xad, 0x14,
30   0x40, 0x55, 0x6f, 0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44, 0xb3, 0xd4,
31   0xfc, 0x45, 0x15, 0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba, 0x37, 0x10,
32   0xa5, 0x89, 0x47, 0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8, 0xb4, 0x7a,
33   0x35, 0xcb, 0x9d, 0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96, 0x94, 0xc4,
34   0xa6, 0x0c, 0x7d, 0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a, 0x0e, 0xc2,
35   0x13, 0xfb, 0xeb, 0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff, 0x72, 0x30,
36   0x05, 0xde, 0x8a, 0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55, 0xd6, 0x2d,
37   0x1d, 0x1e, 0xdb, 0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17, 0x97, 0x98,
38   0x0b, 0x8d, 0x87, 0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab, 0x67, 0x6e,
39   0x87, 0x68, 0x72, 0x23, 0xdc, 0x02, 0x81, 0x80, 0x53, 0x16, 0xb0, 0xfb,
40   0xbf, 0x59, 0x8a, 0x5e, 0x55, 0x95, 0xc1, 0x4f, 0xac, 0x43, 0xb8, 0x08,
41   0x53, 0xe6, 0xcf, 0x0d, 0x92, 0x23, 0xfa, 0xb1, 0x84, 0x59, 0x52, 0x39,
42   0xbf, 0xcb, 0xf2, 0x2d, 0x38, 0x3a, 0xdd, 0x93, 0x52, 0x05, 0x49, 0x7e,
43   0x2b, 0x12, 0xc4, 0x61, 0x73, 0xe3, 0x6f, 0x54, 0xbd, 0x96, 0xe5, 0xa7,
44   0xaa, 0xa9, 0x5a, 0x58, 0xa4, 0xb7, 0x67, 0xd2, 0xc0, 0xbd, 0xc8, 0x1e,
45   0xb1, 0x3a, 0x12, 0x4f, 0x98, 0xc0, 0x05, 0xef, 0x39, 0x5d, 0x6a, 0xba,
46   0xb7, 0x0b, 0x3b, 0xd8, 0xb7, 0x95, 0xdd, 0x79, 0x6e, 0xa2, 0xd2, 0x84,
47   0x73, 0x47, 0x03, 0x88, 0xb4, 0x64, 0xd9, 0xb9, 0xb8, 0x4f, 0xf1, 0xc9,
48   0x34, 0xbb, 0xf9, 0x73, 0x66, 0xf5, 0x7c, 0x2e, 0x11, 0xfe, 0xc3, 0x31,
49   0xe6, 0x08, 0x38, 0x59, 0x67, 0x81, 0xeb, 0x6d, 0x41, 0x27, 0xd7, 0x0d,
50   0x74, 0xaf, 0xa0, 0x35, 0x02, 0x15, 0x00, 0x99, 0x36, 0xe5, 0xe4, 0xe9,
51   0xfb, 0x28, 0xbe, 0x91, 0xf5, 0x06, 0x5f, 0xe8, 0xc9, 0x35, 0xb3, 0xf5,
52   0xd8, 0x1f, 0xc5
53 };
54 
55 /* private key - raw hexadecimal numbers */
56 static const char *hex_g = "3B92E4FF5929150B08995A7BF2AD1440556FA047FF9099B344B3D4FC451505AE6722439CBA3710A5894737ECCCF5AEADA8B47A35CB9D935CEDE6B07E9694C4A60C7DD6708A094F814A0EC213FBEB16BFEAA4F456FF723005DE8A443FBEC6852655D62D1D1EDB15DAA445833C1797980B8D87F3490D90BDA9AB676E87687223DC";
57 static const char *hex_p = "C50A37515CABD618D5A270BD4A6F6B4AF9E139950F2B99387D9A64D64CB5967ADCEDACA8ACC61B655ADEDB0061251A182CEEA10790625E4D123190C70321FA09E7B173D78EAFDBFDBFB3EFADD1A12A036DE706924A852AFF7A0166531FEAC66741845AC06CED62F9C2626205A4FA48A066EC35C9A811FEB981ABEEBE31B6BFCF";
58 static const char *hex_q = "AA5BD7F4E5062413E58835CA00C7A635716194C5";
59 static const char *hex_x = "9936E5E4E9FB28BE91F5065FE8C935B3F5D81FC5";
60 static const char *hex_y = "5316B0FBBF598A5E5595C14FAC43B80853E6CF0D9223FAB184595239BFCBF22D383ADD935205497E2B12C46173E36F54BD96E5A7AAA95A58A4B767D2C0BDC81EB13A124F98C005EF395D6ABAB70B3BD8B795DD796EA2D28473470388B464D9B9B84FF1C934BBF97366F57C2E11FEC331E60838596781EB6D4127D70D74AFA035";
61 
62 /* The public part of test_dsa.key in SubjectPublicKeyInfo format */
63 static const unsigned char openssl_pub_dsa[] = {
64   0x30, 0x82, 0x01, 0xb6, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x07, 0x2a, 0x86,
65   0x48, 0xce, 0x38, 0x04, 0x01, 0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81,
66   0x00, 0xc5, 0x0a, 0x37, 0x51, 0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70,
67   0xbd, 0x4a, 0x6f, 0x6b, 0x4a, 0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99,
68   0x38, 0x7d, 0x9a, 0x64, 0xd6, 0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac,
69   0xa8, 0xac, 0xc6, 0x1b, 0x65, 0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a,
70   0x18, 0x2c, 0xee, 0xa1, 0x07, 0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90,
71   0xc7, 0x03, 0x21, 0xfa, 0x09, 0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb,
72   0xfd, 0xbf, 0xb3, 0xef, 0xad, 0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06,
73   0x92, 0x4a, 0x85, 0x2a, 0xff, 0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6,
74   0x67, 0x41, 0x84, 0x5a, 0xc0, 0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62,
75   0x05, 0xa4, 0xfa, 0x48, 0xa0, 0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe,
76   0xb9, 0x81, 0xab, 0xee, 0xbe, 0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00,
77   0xaa, 0x5b, 0xd7, 0xf4, 0xe5, 0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca,
78   0x00, 0xc7, 0xa6, 0x35, 0x71, 0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b,
79   0x92, 0xe4, 0xff, 0x59, 0x29, 0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2,
80   0xad, 0x14, 0x40, 0x55, 0x6f, 0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44,
81   0xb3, 0xd4, 0xfc, 0x45, 0x15, 0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba,
82   0x37, 0x10, 0xa5, 0x89, 0x47, 0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8,
83   0xb4, 0x7a, 0x35, 0xcb, 0x9d, 0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96,
84   0x94, 0xc4, 0xa6, 0x0c, 0x7d, 0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a,
85   0x0e, 0xc2, 0x13, 0xfb, 0xeb, 0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff,
86   0x72, 0x30, 0x05, 0xde, 0x8a, 0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55,
87   0xd6, 0x2d, 0x1d, 0x1e, 0xdb, 0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17,
88   0x97, 0x98, 0x0b, 0x8d, 0x87, 0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab,
89   0x67, 0x6e, 0x87, 0x68, 0x72, 0x23, 0xdc, 0x03, 0x81, 0x84, 0x00, 0x02,
90   0x81, 0x80, 0x53, 0x16, 0xb0, 0xfb, 0xbf, 0x59, 0x8a, 0x5e, 0x55, 0x95,
91   0xc1, 0x4f, 0xac, 0x43, 0xb8, 0x08, 0x53, 0xe6, 0xcf, 0x0d, 0x92, 0x23,
92   0xfa, 0xb1, 0x84, 0x59, 0x52, 0x39, 0xbf, 0xcb, 0xf2, 0x2d, 0x38, 0x3a,
93   0xdd, 0x93, 0x52, 0x05, 0x49, 0x7e, 0x2b, 0x12, 0xc4, 0x61, 0x73, 0xe3,
94   0x6f, 0x54, 0xbd, 0x96, 0xe5, 0xa7, 0xaa, 0xa9, 0x5a, 0x58, 0xa4, 0xb7,
95   0x67, 0xd2, 0xc0, 0xbd, 0xc8, 0x1e, 0xb1, 0x3a, 0x12, 0x4f, 0x98, 0xc0,
96   0x05, 0xef, 0x39, 0x5d, 0x6a, 0xba, 0xb7, 0x0b, 0x3b, 0xd8, 0xb7, 0x95,
97   0xdd, 0x79, 0x6e, 0xa2, 0xd2, 0x84, 0x73, 0x47, 0x03, 0x88, 0xb4, 0x64,
98   0xd9, 0xb9, 0xb8, 0x4f, 0xf1, 0xc9, 0x34, 0xbb, 0xf9, 0x73, 0x66, 0xf5,
99   0x7c, 0x2e, 0x11, 0xfe, 0xc3, 0x31, 0xe6, 0x08, 0x38, 0x59, 0x67, 0x81,
100   0xeb, 0x6d, 0x41, 0x27, 0xd7, 0x0d, 0x74, 0xaf, 0xa0, 0x35
101 };
102 
103 static unsigned char dsaparam_der[] = {
104    0x30, 0x82, 0x01, 0x1e, 0x02, 0x81, 0x81, 0x00, 0xc5, 0x0a, 0x37, 0x51,
105    0x5c, 0xab, 0xd6, 0x18, 0xd5, 0xa2, 0x70, 0xbd, 0x4a, 0x6f, 0x6b, 0x4a,
106    0xf9, 0xe1, 0x39, 0x95, 0x0f, 0x2b, 0x99, 0x38, 0x7d, 0x9a, 0x64, 0xd6,
107    0x4c, 0xb5, 0x96, 0x7a, 0xdc, 0xed, 0xac, 0xa8, 0xac, 0xc6, 0x1b, 0x65,
108    0x5a, 0xde, 0xdb, 0x00, 0x61, 0x25, 0x1a, 0x18, 0x2c, 0xee, 0xa1, 0x07,
109    0x90, 0x62, 0x5e, 0x4d, 0x12, 0x31, 0x90, 0xc7, 0x03, 0x21, 0xfa, 0x09,
110    0xe7, 0xb1, 0x73, 0xd7, 0x8e, 0xaf, 0xdb, 0xfd, 0xbf, 0xb3, 0xef, 0xad,
111    0xd1, 0xa1, 0x2a, 0x03, 0x6d, 0xe7, 0x06, 0x92, 0x4a, 0x85, 0x2a, 0xff,
112    0x7a, 0x01, 0x66, 0x53, 0x1f, 0xea, 0xc6, 0x67, 0x41, 0x84, 0x5a, 0xc0,
113    0x6c, 0xed, 0x62, 0xf9, 0xc2, 0x62, 0x62, 0x05, 0xa4, 0xfa, 0x48, 0xa0,
114    0x66, 0xec, 0x35, 0xc9, 0xa8, 0x11, 0xfe, 0xb9, 0x81, 0xab, 0xee, 0xbe,
115    0x31, 0xb6, 0xbf, 0xcf, 0x02, 0x15, 0x00, 0xaa, 0x5b, 0xd7, 0xf4, 0xe5,
116    0x06, 0x24, 0x13, 0xe5, 0x88, 0x35, 0xca, 0x00, 0xc7, 0xa6, 0x35, 0x71,
117    0x61, 0x94, 0xc5, 0x02, 0x81, 0x80, 0x3b, 0x92, 0xe4, 0xff, 0x59, 0x29,
118    0x15, 0x0b, 0x08, 0x99, 0x5a, 0x7b, 0xf2, 0xad, 0x14, 0x40, 0x55, 0x6f,
119    0xa0, 0x47, 0xff, 0x90, 0x99, 0xb3, 0x44, 0xb3, 0xd4, 0xfc, 0x45, 0x15,
120    0x05, 0xae, 0x67, 0x22, 0x43, 0x9c, 0xba, 0x37, 0x10, 0xa5, 0x89, 0x47,
121    0x37, 0xec, 0xcc, 0xf5, 0xae, 0xad, 0xa8, 0xb4, 0x7a, 0x35, 0xcb, 0x9d,
122    0x93, 0x5c, 0xed, 0xe6, 0xb0, 0x7e, 0x96, 0x94, 0xc4, 0xa6, 0x0c, 0x7d,
123    0xd6, 0x70, 0x8a, 0x09, 0x4f, 0x81, 0x4a, 0x0e, 0xc2, 0x13, 0xfb, 0xeb,
124    0x16, 0xbf, 0xea, 0xa4, 0xf4, 0x56, 0xff, 0x72, 0x30, 0x05, 0xde, 0x8a,
125    0x44, 0x3f, 0xbe, 0xc6, 0x85, 0x26, 0x55, 0xd6, 0x2d, 0x1d, 0x1e, 0xdb,
126    0x15, 0xda, 0xa4, 0x45, 0x83, 0x3c, 0x17, 0x97, 0x98, 0x0b, 0x8d, 0x87,
127    0xf3, 0x49, 0x0d, 0x90, 0xbd, 0xa9, 0xab, 0x67, 0x6e, 0x87, 0x68, 0x72,
128    0x23, 0xdc
129  };
130 
131 
_dsa_compat_test(void)132 static int _dsa_compat_test(void)
133 {
134   dsa_key key;
135   unsigned char tmp[1024], buf[1024];
136   unsigned long x, len;
137   unsigned char key_parts[5][256];
138   unsigned long key_lens[5];
139   int stat;
140 
141   DO(dsa_import(openssl_priv_dsa, sizeof(openssl_priv_dsa), &key));
142 
143   x = sizeof(tmp);
144   DO(dsa_export(tmp, &x, PK_PRIVATE | PK_STD, &key));
145   if (compare_testvector(tmp, x, openssl_priv_dsa, sizeof(openssl_priv_dsa),
146                          "DSA private export failed from dsa_import(priv_key)\n", __LINE__)) {
147      return CRYPT_FAIL_TESTVECTOR;
148   }
149 
150   x = sizeof(tmp);
151   DO(dsa_export(tmp, &x, PK_PUBLIC | PK_STD, &key));
152   if (compare_testvector(tmp, x, openssl_pub_dsa, sizeof(openssl_pub_dsa),
153                          "DSA public export failed from dsa_import(priv_key)\n", __LINE__)) {
154      return CRYPT_FAIL_TESTVECTOR;
155   }
156   dsa_free(&key);
157 
158   DO(dsa_import(openssl_pub_dsa, sizeof(openssl_pub_dsa), &key));
159 
160   x = sizeof(tmp);
161   DO(dsa_export(tmp, &x, PK_PUBLIC | PK_STD, &key));
162   if (compare_testvector(tmp, x, openssl_pub_dsa, sizeof(openssl_pub_dsa),
163                          "DSA public export failed from dsa_import(pub_key)\n", __LINE__)) {
164      return CRYPT_FAIL_TESTVECTOR;
165   }
166   dsa_free(&key);
167 
168   /* try import private key from raw hexadecimal numbers */
169   for (x = 0; x < 5; ++x) {
170      key_lens[x] = sizeof(key_parts[x]);
171   }
172   DO(radix_to_bin(hex_p, 16, key_parts[0], &key_lens[0]));
173   DO(radix_to_bin(hex_q, 16, key_parts[1], &key_lens[1]));
174   DO(radix_to_bin(hex_g, 16, key_parts[2], &key_lens[2]));
175   DO(radix_to_bin(hex_y, 16, key_parts[3], &key_lens[3]));
176   DO(radix_to_bin(hex_x, 16, key_parts[4], &key_lens[4]));
177 
178   DO(dsa_set_pqg(key_parts[0], key_lens[0],
179                  key_parts[1], key_lens[1],
180                  key_parts[2], key_lens[2],
181                  &key));
182   DO(dsa_set_key(key_parts[4], key_lens[4],
183                  PK_PRIVATE,
184                  &key));
185   len = sizeof(buf);
186   DO(dsa_export(buf, &len, PK_PRIVATE | PK_STD, &key));
187   if (compare_testvector(buf, len, openssl_priv_dsa, sizeof(openssl_priv_dsa),
188                          "DSA private export failed from dsa_set_pqg() & dsa_set_key()\n", __LINE__)) {
189      return CRYPT_FAIL_TESTVECTOR;
190   }
191   dsa_free(&key);
192 
193   /* try import public key from raw hexadecimal numbers */
194   DO(dsa_set_pqg(key_parts[0], key_lens[0],
195                  key_parts[1], key_lens[1],
196                  key_parts[2], key_lens[2],
197                  &key));
198   DO(dsa_set_key(key_parts[3], key_lens[3],
199                  PK_PUBLIC,
200                  &key));
201   len = sizeof(buf);
202   DO(dsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
203   if (compare_testvector(buf, len, openssl_pub_dsa, sizeof(openssl_pub_dsa),
204                          "DSA public export failed from dsa_set_pqg() & dsa_set_key()\n", __LINE__)) {
205      return CRYPT_FAIL_TESTVECTOR;
206   }
207   dsa_free(&key);
208 
209   /* try import dsaparam */
210   DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
211   DO(dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key));
212   /* verify it */
213   DO(dsa_verify_key(&key, &stat));
214   if (stat == 0) {
215      fprintf(stderr, "dsa_verify_key after dsa_set_pqg_dsaparam()");
216      return CRYPT_FAIL_TESTVECTOR;
217   }
218   dsa_free(&key);
219 
220   /* try import dsaparam - our public key */
221   DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
222   DO(dsa_set_key(key_parts[3], key_lens[3],
223                  PK_PUBLIC,
224                  &key));
225   len = sizeof(buf);
226   DO(dsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
227   if (compare_testvector(buf, len, openssl_pub_dsa, sizeof(openssl_pub_dsa),
228                          "DSA public export failed from dsa_set_pqg_dsaparam()\n", __LINE__)) {
229      return CRYPT_FAIL_TESTVECTOR;
230   }
231   dsa_free(&key);
232 
233   /* try import dsaparam - our private key */
234   DO(dsa_set_pqg_dsaparam(dsaparam_der, sizeof(dsaparam_der), &key));
235   DO(dsa_set_key(key_parts[4], key_lens[4],
236                  PK_PRIVATE,
237                  &key));
238   len = sizeof(buf);
239   DO(dsa_export(buf, &len, PK_PRIVATE | PK_STD, &key));
240   if (compare_testvector(buf, len, openssl_priv_dsa, sizeof(openssl_priv_dsa),
241                          "DSA private export failed from dsa_set_pqg_dsaparam()\n", __LINE__)) {
242      return CRYPT_FAIL_TESTVECTOR;
243   }
244   dsa_free(&key);
245 
246   return CRYPT_OK;
247 }
248 
_dsa_wycheproof_test(void)249 static int _dsa_wycheproof_test(void)
250 {
251    /* test case from https://github.com/google/wycheproof/blob/master/testvectors/dsa_test.json
252     *
253     * "comment" : "appending unused 0's",
254     * "message" : "48656c6c6f",
255     * "result" : "invalid",
256     * "sig" : "303d021c1e41b479ad576905b960fe14eadb91b0ccf34843dab916173bb8c9cd021d00ade65988d237d30f9ef41dd424a4e1c8f16967cf3365813fe87862360000",
257     * "tcId" : 55
258     */
259    unsigned char msg[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f };
260    unsigned char sig[] = { 0x30, 0x3d, 0x02, 0x1c, 0x1e, 0x41, 0xb4, 0x79, 0xad, 0x57, 0x69, 0x05, 0xb9, 0x60, 0xfe,
261                            0x14, 0xea, 0xdb, 0x91, 0xb0, 0xcc, 0xf3, 0x48, 0x43, 0xda, 0xb9, 0x16, 0x17, 0x3b, 0xb8,
262                            0xc9, 0xcd, 0x02, 0x1d, 0x00, 0xad, 0xe6, 0x59, 0x88, 0xd2, 0x37, 0xd3, 0x0f, 0x9e, 0xf4,
263                            0x1d, 0xd4, 0x24, 0xa4, 0xe1, 0xc8, 0xf1, 0x69, 0x67, 0xcf, 0x33, 0x65, 0x81, 0x3f, 0xe8,
264                            0x78, 0x62, 0x36, 0x00, 0x00 };
265    const char* b64key =
266       "MIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7FnjuvNxjo6sSWHz79"
267       "NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwOjxSzNggooi/6JxEKPWKpk0U0CaD+"
268       "aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYpH51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGM"
269       "n/qdgYHnM423krcw17njSVkvaAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOTh"
270       "jBopo33fXqFD3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0A"
271       "uvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQNNNo6NHjBVNTk"
272       "pcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJsyB2p5wypifyRz6Rh5uixOdE"
273       "vSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjGjQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH"
274       "9kxoJts+xy9LVZmDS7TtsC98kOmkltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh+"
275       "+1/et1SEMWsiMt7lU92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHv"
276       "F9veA4IBBQACggEAHnf4QrGuD82ZKdOUFh1B4UYU/3UHqaMfSh8U0i4qYnofTllmJIg/GlsWjpQl"
277       "FG8i1fbuKHV0FHFLuZS6ESnwFdbgSnF+35tTCl1cq5TxRjHotM95rrNYzHQYRVU4QeisRhYw6ASm"
278       "L0Nna6Z5SvZomcN3uGnqYSp7n+ZhGqlr5S64tiyXkRe7vMqKfsHh/6scffz8cEhwDTrjhYE26Jdw"
279       "HXwpIbXf7x0fiX9Q2WyhtcLtxYytoYkZ41ZC8IB+6/oAyZoy9NCVwxiPeO1UcRvgMlxLUyrszWVA"
280       "pWfDJyJUQOoVMZveBlEEeaGGF5niW1fezHPANtdaBwK9NzyiMTSZMQ==";
281    unsigned char derkey[838];
282    unsigned long derlen = sizeof(derkey);
283    unsigned char hash[32];
284    unsigned long hashlen = sizeof(hash);
285    dsa_key key;
286    int stat;
287 
288    DO(base64_decode((unsigned char*)b64key, strlen(b64key), derkey, &derlen));
289    if (derlen != 838) {
290       fprintf(stderr, "base64_decode failed, derlen=%lu (expected 838)\n", derlen);
291       return CRYPT_FAIL_TESTVECTOR;
292    }
293    DO(dsa_import(derkey, derlen, &key));
294    DO(hash_memory(find_hash("sha224"), msg, sizeof(msg), hash, &hashlen));
295    if (hashlen != 28) {
296       fprintf(stderr, "hash_memory failed, hashlen=%lu (expected 32)\n", hashlen);
297       return CRYPT_FAIL_TESTVECTOR;
298    }
299 
300    stat = 666; /* intentionally not one, not zero */
301    DO(dsa_verify_hash(sig, sizeof(sig)-2, hash, hashlen, &stat, &key));
302    /* without the last two 0x00 bytes it is a valid signature */
303    if (stat != 1) {
304       fprintf(stderr, "dsa_verify_hash rejected valid signature\n");
305       return CRYPT_FAIL_TESTVECTOR;
306    }
307 
308    stat = 666; /* intentionally not one, not zero */
309    DO(dsa_verify_hash(sig, sizeof(sig), hash, hashlen, &stat, &key));
310    /* this should be invalid */
311    if (stat != 0) {
312       fprintf(stderr, "dsa_verify_hash did not reject invalid signature\n");
313       return CRYPT_FAIL_TESTVECTOR;
314    }
315 
316    dsa_free(&key);
317    return CRYPT_OK;
318 }
319 
dsa_test(void)320 int dsa_test(void)
321 {
322    unsigned char msg[16], out[1024], out2[1024], ch;
323    unsigned long x, y;
324    int stat1, stat2;
325    dsa_key key, key2;
326 
327    DO(_dsa_compat_test());
328    DO(_dsa_wycheproof_test());
329 
330    /* make a random key */
331    DO(dsa_generate_pqg(&yarrow_prng, find_prng("yarrow"), 20, 128, &key));
332    DO(dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key));
333 
334    /* verify it */
335    DO(dsa_verify_key(&key, &stat1));
336    if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; }
337 
338    /* encrypt a message */
339    for (ch = 0; ch < 16; ch++) { msg[ch] = ch; }
340    x = sizeof(out);
341    DO(dsa_encrypt_key(msg, 16, out, &x, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key));
342 
343    /* decrypt */
344    y = sizeof(out2);
345    DO(dsa_decrypt_key(out, x, out2, &y, &key));
346 
347    if (y != 16 || memcmp(out2, msg, 16)) {
348       fprintf(stderr, "dsa_decrypt failed, y == %lu\n", y);
349       return 1;
350    }
351 
352    /* sign the message */
353    x = sizeof(out);
354    DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &yarrow_prng, find_prng("yarrow"), &key));
355 
356    /* verify it once */
357    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key));
358 
359    /* Modify and verify again */
360    msg[0] ^= 1;
361    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
362    msg[0] ^= 1;
363    if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; }
364 
365    /* test exporting it */
366    y = sizeof(out2);
367    DO(dsa_export(out2, &y, PK_PRIVATE, &key));
368    DO(dsa_import(out2, y, &key2));
369 
370    /* verify a signature with it */
371    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
372    if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; }
373    dsa_free(&key2);
374 
375    /* export as public now */
376    y = sizeof(out2);
377    DO(dsa_export(out2, &y, PK_PUBLIC, &key));
378 
379    DO(dsa_import(out2, y, &key2));
380    /* verify a signature with it */
381    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
382    if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; }
383    dsa_free(&key2);
384    dsa_free(&key);
385 
386    return 0;
387 }
388 
389 #else
390 
dsa_test(void)391 int dsa_test(void)
392 {
393   return CRYPT_NOP;
394 }
395 
396 #endif
397 
398 /* ref:         $Format:%D$ */
399 /* git commit:  $Format:%H$ */
400 /* commit time: $Format:%ai$ */
401