Imported Upstream version 1.15.1
[platform/upstream/krb5.git] / src / lib / crypto / crypto_tests / t_cksums.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/crypto_tests/t_cksums.c - Test known checksum results */
3 /*
4  * Copyright (C) 2010 by the Massachusetts Institute of Technology.
5  * All rights reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  *
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  Furthermore if you modify this software you must label
20  * your software as modified software and not distribute it in such a
21  * fashion that it might be confused with the original M.I.T. software.
22  * M.I.T. makes no representations about the suitability of
23  * this software for any purpose.  It is provided "as is" without express
24  * or implied warranty.
25  */
26
27 /*
28  * This harness tests checksum results against known values.  With the -v flag,
29  * results for all tests are displayed.  This harness only works for
30  * deterministic checksums; for rsa-md4-des and rsa-md5-des, see t_cksum.c.
31  */
32
33 #include "k5-int.h"
34
35 struct test {
36     krb5_data plaintext;
37     krb5_cksumtype sumtype;
38     krb5_enctype enctype;
39     krb5_keyusage usage;
40     krb5_data keybits;
41     krb5_data cksum;
42 } test_cases[] = {
43     {
44         { KV5M_DATA, 3, "abc" },
45         CKSUMTYPE_CRC32, 0, 0, { KV5M_DATA, 0, "" },
46         { KV5M_DATA, 4,
47           "\xD0\x98\x65\xCA" }
48     },
49     {
50         { KV5M_DATA, 3, "one" },
51         CKSUMTYPE_RSA_MD4, 0, 0, { KV5M_DATA, 0, "" },
52         { KV5M_DATA, 16,
53           "\x30\x5D\xCC\x2C\x0F\xDD\x53\x39\x96\x95\x52\xC7\xB8\x99\x63\x48" }
54     },
55     {
56         { KV5M_DATA, 19, "two three four five" },
57         CKSUMTYPE_RSA_MD5, 0, 0, { KV5M_DATA, 0, "" },
58         { KV5M_DATA, 16,
59           "\xBA\xB5\x32\x15\x51\xE1\x08\x44\x90\x86\x96\x35\xB3\xC2\x68\x15" }
60     },
61     {
62         { KV5M_DATA, 0, "" },
63         CKSUMTYPE_NIST_SHA, 0, 0, { KV5M_DATA, 0, "" },
64         { KV5M_DATA, 20,
65           "\xDA\x39\xA3\xEE\x5E\x6B\x4B\x0D\x32\x55\xBF\xEF\x95\x60\x18\x90"
66           "\xAF\xD8\x07\x09" }
67     },
68     {
69         { KV5M_DATA, 9, "six seven" },
70         CKSUMTYPE_HMAC_SHA1_DES3, ENCTYPE_DES3_CBC_SHA1, 2,
71         { KV5M_DATA, 24,
72           "\x7A\x25\xDF\x89\x92\x29\x6D\xCE\xDA\x0E\x13\x5B\xC4\x04\x6E\x23"
73           "\x75\xB3\xC1\x4C\x98\xFB\xC1\x62" },
74         { KV5M_DATA, 20,
75           "\x0E\xEF\xC9\xC3\xE0\x49\xAA\xBC\x1B\xA5\xC4\x01\x67\x7D\x9A\xB6"
76           "\x99\x08\x2B\xB4" }
77     },
78     {
79         { KV5M_DATA, 37, "eight nine ten eleven twelve thirteen" },
80         CKSUMTYPE_HMAC_SHA1_96_AES128, ENCTYPE_AES128_CTS_HMAC_SHA1_96, 3,
81         { KV5M_DATA, 16,
82           "\x90\x62\x43\x0C\x8C\xDA\x33\x88\x92\x2E\x6D\x6A\x50\x9F\x5B\x7A" },
83         { KV5M_DATA, 12,
84           "\x01\xA4\xB0\x88\xD4\x56\x28\xF6\x94\x66\x14\xE3" }
85     },
86     {
87         { KV5M_DATA, 8, "fourteen" },
88         CKSUMTYPE_HMAC_SHA1_96_AES256, ENCTYPE_AES256_CTS_HMAC_SHA1_96, 4,
89         { KV5M_DATA, 32,
90           "\xB1\xAE\x4C\xD8\x46\x2A\xFF\x16\x77\x05\x3C\xC9\x27\x9A\xAC\x30"
91           "\xB7\x96\xFB\x81\xCE\x21\x47\x4D\xD3\xDD\xBC\xFE\xA4\xEC\x76\xD7" },
92         { KV5M_DATA, 12,
93           "\xE0\x87\x39\xE3\x27\x9E\x29\x03\xEC\x8E\x38\x36" }
94     },
95     {
96         { KV5M_DATA, 15, "fifteen sixteen" },
97         CKSUMTYPE_MD5_HMAC_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 5,
98         { KV5M_DATA, 16,
99           "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" },
100         { KV5M_DATA, 16,
101           "\x9F\x41\xDF\x30\x49\x07\xDE\x73\x54\x47\x00\x1F\xD2\xA1\x97\xB9" }
102     },
103     {
104         { KV5M_DATA, 34, "seventeen eighteen nineteen twenty" },
105         CKSUMTYPE_HMAC_MD5_ARCFOUR, ENCTYPE_ARCFOUR_HMAC, 6,
106         { KV5M_DATA, 16,
107           "\xF7\xD3\xA1\x55\xAF\x5E\x23\x8A\x0B\x7A\x87\x1A\x96\xBA\x2A\xB2" },
108         { KV5M_DATA, 16,
109           "\xEB\x38\xCC\x97\xE2\x23\x0F\x59\xDA\x41\x17\xDC\x58\x59\xD7\xEC" }
110     },
111     {
112         { KV5M_DATA, 11, "abcdefghijk" },
113         CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 7,
114         { KV5M_DATA, 16,
115           "\x1D\xC4\x6A\x8D\x76\x3F\x4F\x93\x74\x2B\xCB\xA3\x38\x75\x76\xC3" },
116         { KV5M_DATA, 16,
117           "\x11\x78\xE6\xC5\xC4\x7A\x8C\x1A\xE0\xC4\xB9\xC7\xD4\xEB\x7B\x6B" }
118     },
119     {
120         { KV5M_DATA, 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
121         CKSUMTYPE_CMAC_CAMELLIA128, ENCTYPE_CAMELLIA128_CTS_CMAC, 8,
122         { KV5M_DATA, 16,
123           "\x50\x27\xBC\x23\x1D\x0F\x3A\x9D\x23\x33\x3F\x1C\xA6\xFD\xBE\x7C" },
124         { KV5M_DATA, 16,
125           "\xD1\xB3\x4F\x70\x04\xA7\x31\xF2\x3A\x0C\x00\xBF\x6C\x3F\x75\x3A" }
126     },
127     {
128         { KV5M_DATA, 9, "123456789" },
129         CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 9,
130         { KV5M_DATA, 32,
131           "\xB6\x1C\x86\xCC\x4E\x5D\x27\x57\x54\x5A\xD4\x23\x39\x9F\xB7\x03"
132           "\x1E\xCA\xB9\x13\xCB\xB9\x00\xBD\x7A\x3C\x6D\xD8\xBF\x92\x01\x5B" },
133         { KV5M_DATA, 16,
134           "\x87\xA1\x2C\xFD\x2B\x96\x21\x48\x10\xF0\x1C\x82\x6E\x77\x44\xB1" }
135     },
136     {
137         { KV5M_DATA, 30, "!@#$%^&*()!@#$%^&*()!@#$%^&*()" },
138         CKSUMTYPE_CMAC_CAMELLIA256, ENCTYPE_CAMELLIA256_CTS_CMAC, 10,
139         { KV5M_DATA, 32,
140           "\x32\x16\x4C\x5B\x43\x4D\x1D\x15\x38\xE4\xCF\xD9\xBE\x80\x40\xFE"
141           "\x8C\x4A\xC7\xAC\xC4\xB9\x3D\x33\x14\xD2\x13\x36\x68\x14\x7A\x05" },
142         { KV5M_DATA, 16,
143           "\x3F\xA0\xB4\x23\x55\xE5\x2B\x18\x91\x87\x29\x4A\xA2\x52\xAB\x64" }
144     },
145     {
146         { KV5M_DATA, 21,
147           "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
148           "\x10\x11\x12\x13\x14" },
149         CKSUMTYPE_HMAC_SHA256_128_AES128, ENCTYPE_AES128_CTS_HMAC_SHA256_128,
150         2,
151         { KV5M_DATA, 16,
152           "\x37\x05\xD9\x60\x80\xC1\x77\x28\xA0\xE8\x00\xEA\xB6\xE0\xD2\x3C" },
153         { KV5M_DATA, 16,
154           "\xD7\x83\x67\x18\x66\x43\xD6\x7B\x41\x1C\xBA\x91\x39\xFC\x1D\xEE" }
155     },
156     {
157         { KV5M_DATA, 21,
158           "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
159           "\x10\x11\x12\x13\x14" },
160         CKSUMTYPE_HMAC_SHA384_192_AES256, ENCTYPE_AES256_CTS_HMAC_SHA384_192,
161         2,
162         { KV5M_DATA, 32,
163           "\x6D\x40\x4D\x37\xFA\xF7\x9F\x9D\xF0\xD3\x35\x68\xD3\x20\x66\x98"
164           "\x00\xEB\x48\x36\x47\x2E\xA8\xA0\x26\xD1\x6B\x71\x82\x46\x0C\x52" },
165         { KV5M_DATA, 24,
166           "\x45\xEE\x79\x15\x67\xEE\xFC\xA3\x7F\x4A\xC1\xE0\x22\x2D\xE8\x0D"
167           "\x43\xC3\xBF\xA0\x66\x99\x67\x2A" }
168     },
169 };
170
171 static void
172 printhex(const char *head, void *data, size_t len)
173 {
174     size_t i;
175
176     printf("%s", head);
177     for (i = 0; i < len; i++) {
178 #if 0                           /* For convenience when updating test cases. */
179         printf("\\x%02X", ((unsigned char*)data)[i]);
180 #else
181         printf("%02X", ((unsigned char*)data)[i]);
182         if (i % 16 == 15 && i + 1 < len)
183             printf("\n%*s", (int)strlen(head), "");
184         else if (i + 1 < len)
185             printf(" ");
186 #endif
187     }
188     printf("\n");
189 }
190
191 int
192 main(int argc, char **argv)
193 {
194     krb5_error_code ret;
195     krb5_context context = NULL;
196     size_t i;
197     struct test *test;
198     krb5_keyblock kb, *kbp;
199     krb5_checksum cksum;
200     krb5_cksumtype mtype;
201     krb5_boolean valid, verbose = FALSE;
202     int status = 0;
203
204     if (argc >= 2 && strcmp(argv[1], "-v") == 0)
205         verbose = TRUE;
206     for (i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
207         test = &test_cases[i];
208         if (test->enctype != 0) {
209             kb.magic = KV5M_KEYBLOCK;
210             kb.enctype = test->enctype;
211             kb.length = test->keybits.length;
212             kb.contents = (unsigned char *)test->keybits.data;
213             kbp = &kb;
214         } else
215             kbp = NULL;
216         ret = krb5_c_make_checksum(context, test->sumtype, kbp, test->usage,
217                                    &test->plaintext, &cksum);
218         assert(!ret);
219         if (verbose) {
220             char buf[64];
221             krb5_cksumtype_to_string(test->sumtype, buf, sizeof(buf));
222             printf("\nTest %d:\n", (int)i);
223             printf("Plaintext: %.*s\n", (int)test->plaintext.length,
224                    test->plaintext.data);
225             printf("Checksum type: %s\n", buf);
226             if (test->enctype != 0) {
227                 krb5_enctype_to_name(test->enctype, FALSE, buf, sizeof(buf));
228                 printf("Enctype: %s\n", buf);
229                 printhex("Key: ", test->keybits.data, test->keybits.length);
230                 printf("Key usage: %d\n", (int)test->usage);
231             }
232             printhex("Checksum: ", cksum.contents, cksum.length);
233         }
234         if (test->cksum.length != cksum.length ||
235             memcmp(test->cksum.data, cksum.contents, cksum.length) != 0) {
236             printf("derive test %d failed\n", (int)i);
237             status = 1;
238             if (!verbose)
239                 break;
240         }
241
242         /* Test that the checksum verifies successfully. */
243         ret = krb5_c_verify_checksum(context, kbp, test->usage,
244                                      &test->plaintext, &cksum, &valid);
245         assert(!ret);
246         if (!valid) {
247             printf("test %d verify failed\n", (int)i);
248             status = 1;
249             if (!verbose)
250                 break;
251         }
252
253         if (kbp != NULL) {
254             ret = krb5int_c_mandatory_cksumtype(context, kbp->enctype, &mtype);
255             assert(!ret);
256             if (test->sumtype == mtype) {
257                 /* Test that a checksum type of 0 uses the mandatory checksum
258                  * type for the key. */
259                 cksum.checksum_type = 0;
260                 ret = krb5_c_verify_checksum(context, kbp, test->usage,
261                                              &test->plaintext, &cksum, &valid);
262                 assert(!ret && valid);
263             }
264         }
265
266         krb5_free_checksum_contents(context, &cksum);
267     }
268     return status;
269 }