xref: /minix3/crypto/external/bsd/heimdal/dist/lib/krb5/aes-test.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: aes-test.c,v 1.1.1.2 2014/04/24 12:45:49 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 2003 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc  * are met:
11ebfedea0SLionel Sambuc  *
12ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc  *
15ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc  *
19ebfedea0SLionel Sambuc  * 3. Neither the name of KTH nor the names of its contributors may be
20ebfedea0SLionel Sambuc  *    used to endorse or promote products derived from this software without
21ebfedea0SLionel Sambuc  *    specific prior written permission.
22ebfedea0SLionel Sambuc  *
23ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24ebfedea0SLionel Sambuc  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26ebfedea0SLionel Sambuc  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27ebfedea0SLionel Sambuc  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28ebfedea0SLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29ebfedea0SLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30ebfedea0SLionel Sambuc  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31ebfedea0SLionel Sambuc  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32ebfedea0SLionel Sambuc  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33ebfedea0SLionel Sambuc  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
34ebfedea0SLionel Sambuc 
35ebfedea0SLionel Sambuc #include "krb5_locl.h"
36ebfedea0SLionel Sambuc #include <krb5/hex.h>
37ebfedea0SLionel Sambuc #include <err.h>
38ebfedea0SLionel Sambuc #include <assert.h>
39ebfedea0SLionel Sambuc 
40ebfedea0SLionel Sambuc #ifdef HAVE_OPENSSL
41ebfedea0SLionel Sambuc #include <openssl/evp.h>
42ebfedea0SLionel Sambuc #endif
43ebfedea0SLionel Sambuc 
44ebfedea0SLionel Sambuc static int verbose = 0;
45ebfedea0SLionel Sambuc 
46ebfedea0SLionel Sambuc static void
hex_dump_data(const void * data,size_t length)47ebfedea0SLionel Sambuc hex_dump_data(const void *data, size_t length)
48ebfedea0SLionel Sambuc {
49ebfedea0SLionel Sambuc     char *p;
50ebfedea0SLionel Sambuc 
51ebfedea0SLionel Sambuc     hex_encode(data, length, &p);
52ebfedea0SLionel Sambuc     printf("%s\n", p);
53ebfedea0SLionel Sambuc     free(p);
54ebfedea0SLionel Sambuc }
55ebfedea0SLionel Sambuc 
56ebfedea0SLionel Sambuc struct {
57ebfedea0SLionel Sambuc     char *password;
58ebfedea0SLionel Sambuc     char *salt;
59ebfedea0SLionel Sambuc     int saltlen;
60ebfedea0SLionel Sambuc     int iterations;
61ebfedea0SLionel Sambuc     krb5_enctype enctype;
62ebfedea0SLionel Sambuc     size_t keylen;
63ebfedea0SLionel Sambuc     char *pbkdf2;
64ebfedea0SLionel Sambuc     char *key;
65ebfedea0SLionel Sambuc } keys[] = {
66ebfedea0SLionel Sambuc     {
67ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
68ebfedea0SLionel Sambuc 	1,
69ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
70ebfedea0SLionel Sambuc 	"\xcd\xed\xb5\x28\x1b\xb2\xf8\x01\x56\x5a\x11\x22\xb2\x56\x35\x15",
71ebfedea0SLionel Sambuc 	"\x42\x26\x3c\x6e\x89\xf4\xfc\x28\xb8\xdf\x68\xee\x09\x79\x9f\x15"
72ebfedea0SLionel Sambuc     },
73ebfedea0SLionel Sambuc     {
74ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
75ebfedea0SLionel Sambuc 	1,
76ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
77ebfedea0SLionel Sambuc 	"\xcd\xed\xb5\x28\x1b\xb2\xf8\x01\x56\x5a\x11\x22\xb2\x56\x35\x15"
78ebfedea0SLionel Sambuc 	"\x0a\xd1\xf7\xa0\x4b\xb9\xf3\xa3\x33\xec\xc0\xe2\xe1\xf7\x08\x37",
79ebfedea0SLionel Sambuc 	"\xfe\x69\x7b\x52\xbc\x0d\x3c\xe1\x44\x32\xba\x03\x6a\x92\xe6\x5b"
80ebfedea0SLionel Sambuc 	"\xbb\x52\x28\x09\x90\xa2\xfa\x27\x88\x39\x98\xd7\x2a\xf3\x01\x61"
81ebfedea0SLionel Sambuc     },
82ebfedea0SLionel Sambuc     {
83ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
84ebfedea0SLionel Sambuc 	2,
85ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
86ebfedea0SLionel Sambuc 	"\x01\xdb\xee\x7f\x4a\x9e\x24\x3e\x98\x8b\x62\xc7\x3c\xda\x93\x5d",
87ebfedea0SLionel Sambuc 	"\xc6\x51\xbf\x29\xe2\x30\x0a\xc2\x7f\xa4\x69\xd6\x93\xbd\xda\x13"
88ebfedea0SLionel Sambuc     },
89ebfedea0SLionel Sambuc     {
90ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
91ebfedea0SLionel Sambuc 	2,
92ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
93ebfedea0SLionel Sambuc 	"\x01\xdb\xee\x7f\x4a\x9e\x24\x3e\x98\x8b\x62\xc7\x3c\xda\x93\x5d"
94ebfedea0SLionel Sambuc 	"\xa0\x53\x78\xb9\x32\x44\xec\x8f\x48\xa9\x9e\x61\xad\x79\x9d\x86",
95ebfedea0SLionel Sambuc 	"\xa2\xe1\x6d\x16\xb3\x60\x69\xc1\x35\xd5\xe9\xd2\xe2\x5f\x89\x61"
96ebfedea0SLionel Sambuc 	"\x02\x68\x56\x18\xb9\x59\x14\xb4\x67\xc6\x76\x22\x22\x58\x24\xff"
97ebfedea0SLionel Sambuc     },
98ebfedea0SLionel Sambuc     {
99ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
100ebfedea0SLionel Sambuc 	1200,
101ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
102ebfedea0SLionel Sambuc 	"\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b",
103ebfedea0SLionel Sambuc 	"\x4c\x01\xcd\x46\xd6\x32\xd0\x1e\x6d\xbe\x23\x0a\x01\xed\x64\x2a"
104ebfedea0SLionel Sambuc     },
105ebfedea0SLionel Sambuc     {
106ebfedea0SLionel Sambuc 	"password", "ATHENA.MIT.EDUraeburn", -1,
107ebfedea0SLionel Sambuc 	1200,
108ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
109ebfedea0SLionel Sambuc 	"\x5c\x08\xeb\x61\xfd\xf7\x1e\x4e\x4e\xc3\xcf\x6b\xa1\xf5\x51\x2b"
110ebfedea0SLionel Sambuc 	"\xa7\xe5\x2d\xdb\xc5\xe5\x14\x2f\x70\x8a\x31\xe2\xe6\x2b\x1e\x13",
111ebfedea0SLionel Sambuc 	"\x55\xa6\xac\x74\x0a\xd1\x7b\x48\x46\x94\x10\x51\xe1\xe8\xb0\xa7"
112ebfedea0SLionel Sambuc 	"\x54\x8d\x93\xb0\xab\x30\xa8\xbc\x3f\xf1\x62\x80\x38\x2b\x8c\x2a"
113ebfedea0SLionel Sambuc     },
114ebfedea0SLionel Sambuc     {
115ebfedea0SLionel Sambuc 	"password", "\x12\x34\x56\x78\x78\x56\x34\x12", 8,
116ebfedea0SLionel Sambuc 	5,
117ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
118ebfedea0SLionel Sambuc 	"\xd1\xda\xa7\x86\x15\xf2\x87\xe6\xa1\xc8\xb1\x20\xd7\x06\x2a\x49",
119ebfedea0SLionel Sambuc 	"\xe9\xb2\x3d\x52\x27\x37\x47\xdd\x5c\x35\xcb\x55\xbe\x61\x9d\x8e"
120ebfedea0SLionel Sambuc     },
121ebfedea0SLionel Sambuc     {
122ebfedea0SLionel Sambuc 	"password", "\x12\x34\x56\x78\x78\x56\x34\x12", 8,
123ebfedea0SLionel Sambuc 	5,
124ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
125ebfedea0SLionel Sambuc 	"\xd1\xda\xa7\x86\x15\xf2\x87\xe6\xa1\xc8\xb1\x20\xd7\x06\x2a\x49"
126ebfedea0SLionel Sambuc 	"\x3f\x98\xd2\x03\xe6\xbe\x49\xa6\xad\xf4\xfa\x57\x4b\x6e\x64\xee",
127ebfedea0SLionel Sambuc 	"\x97\xa4\xe7\x86\xbe\x20\xd8\x1a\x38\x2d\x5e\xbc\x96\xd5\x90\x9c"
128ebfedea0SLionel Sambuc 	"\xab\xcd\xad\xc8\x7c\xa4\x8f\x57\x45\x04\x15\x9f\x16\xc3\x6e\x31"
129ebfedea0SLionel Sambuc     },
130ebfedea0SLionel Sambuc     {
131ebfedea0SLionel Sambuc 	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
132ebfedea0SLionel Sambuc 	"pass phrase equals block size", -1,
133ebfedea0SLionel Sambuc 	1200,
134ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
135ebfedea0SLionel Sambuc 	"\x13\x9c\x30\xc0\x96\x6b\xc3\x2b\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9",
136ebfedea0SLionel Sambuc 	"\x59\xd1\xbb\x78\x9a\x82\x8b\x1a\xa5\x4e\xf9\xc2\x88\x3f\x69\xed"
137ebfedea0SLionel Sambuc     },
138ebfedea0SLionel Sambuc     {
139ebfedea0SLionel Sambuc 	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
140ebfedea0SLionel Sambuc 	"pass phrase equals block size", -1,
141ebfedea0SLionel Sambuc 	1200,
142ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
143ebfedea0SLionel Sambuc 	"\x13\x9c\x30\xc0\x96\x6b\xc3\x2b\xa5\x5f\xdb\xf2\x12\x53\x0a\xc9"
144ebfedea0SLionel Sambuc 	"\xc5\xec\x59\xf1\xa4\x52\xf5\xcc\x9a\xd9\x40\xfe\xa0\x59\x8e\xd1",
145ebfedea0SLionel Sambuc 	"\x89\xad\xee\x36\x08\xdb\x8b\xc7\x1f\x1b\xfb\xfe\x45\x94\x86\xb0"
146ebfedea0SLionel Sambuc 	"\x56\x18\xb7\x0c\xba\xe2\x20\x92\x53\x4e\x56\xc5\x53\xba\x4b\x34"
147ebfedea0SLionel Sambuc     },
148ebfedea0SLionel Sambuc     {
149ebfedea0SLionel Sambuc 	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
150ebfedea0SLionel Sambuc 	"pass phrase exceeds block size", -1,
151ebfedea0SLionel Sambuc 	1200,
152ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
153ebfedea0SLionel Sambuc 	"\x9c\xca\xd6\xd4\x68\x77\x0c\xd5\x1b\x10\xe6\xa6\x87\x21\xbe\x61",
154ebfedea0SLionel Sambuc 	"\xcb\x80\x05\xdc\x5f\x90\x17\x9a\x7f\x02\x10\x4c\x00\x18\x75\x1d"
155ebfedea0SLionel Sambuc     },
156ebfedea0SLionel Sambuc     {
157ebfedea0SLionel Sambuc 	"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
158ebfedea0SLionel Sambuc 	"pass phrase exceeds block size", -1,
159ebfedea0SLionel Sambuc 	1200,
160ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
161ebfedea0SLionel Sambuc 	"\x9c\xca\xd6\xd4\x68\x77\x0c\xd5\x1b\x10\xe6\xa6\x87\x21\xbe\x61"
162ebfedea0SLionel Sambuc 	"\x1a\x8b\x4d\x28\x26\x01\xdb\x3b\x36\xbe\x92\x46\x91\x5e\xc8\x2a",
163ebfedea0SLionel Sambuc 	"\xd7\x8c\x5c\x9c\xb8\x72\xa8\xc9\xda\xd4\x69\x7f\x0b\xb5\xb2\xd2"
164ebfedea0SLionel Sambuc 	"\x14\x96\xc8\x2b\xeb\x2c\xae\xda\x21\x12\xfc\xee\xa0\x57\x40\x1b"
165ebfedea0SLionel Sambuc 
166ebfedea0SLionel Sambuc     },
167ebfedea0SLionel Sambuc     {
168ebfedea0SLionel Sambuc 	"\xf0\x9d\x84\x9e" /* g-clef */, "EXAMPLE.COMpianist", -1,
169ebfedea0SLionel Sambuc 	50,
170ebfedea0SLionel Sambuc 	ETYPE_AES128_CTS_HMAC_SHA1_96, 16,
171ebfedea0SLionel Sambuc 	"\x6b\x9c\xf2\x6d\x45\x45\x5a\x43\xa5\xb8\xbb\x27\x6a\x40\x3b\x39",
172ebfedea0SLionel Sambuc 	"\xf1\x49\xc1\xf2\xe1\x54\xa7\x34\x52\xd4\x3e\x7f\xe6\x2a\x56\xe5"
173ebfedea0SLionel Sambuc     },
174ebfedea0SLionel Sambuc     {
175ebfedea0SLionel Sambuc 	"\xf0\x9d\x84\x9e" /* g-clef */, "EXAMPLE.COMpianist", -1,
176ebfedea0SLionel Sambuc 	50,
177ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96, 32,
178ebfedea0SLionel Sambuc 	"\x6b\x9c\xf2\x6d\x45\x45\x5a\x43\xa5\xb8\xbb\x27\x6a\x40\x3b\x39"
179ebfedea0SLionel Sambuc 	"\xe7\xfe\x37\xa0\xc4\x1e\x02\xc2\x81\xff\x30\x69\xe1\xe9\x4f\x52",
180ebfedea0SLionel Sambuc 	"\x4b\x6d\x98\x39\xf8\x44\x06\xdf\x1f\x09\xcc\x16\x6d\xb4\xb8\x3c"
181ebfedea0SLionel Sambuc 	"\x57\x18\x48\xb7\x84\xa3\xd6\xbd\xc3\x46\x58\x9a\x3e\x39\x3f\x9e"
182ebfedea0SLionel Sambuc     },
183ebfedea0SLionel Sambuc     {
184ebfedea0SLionel Sambuc 	"foo", "", -1,
185ebfedea0SLionel Sambuc 	0,
186ebfedea0SLionel Sambuc 	ETYPE_ARCFOUR_HMAC_MD5, 16,
187ebfedea0SLionel Sambuc 	NULL,
188ebfedea0SLionel Sambuc 	"\xac\x8e\x65\x7f\x83\xdf\x82\xbe\xea\x5d\x43\xbd\xaf\x78\x00\xcc"
189ebfedea0SLionel Sambuc     },
190ebfedea0SLionel Sambuc     {
191ebfedea0SLionel Sambuc 	"test", "", -1,
192ebfedea0SLionel Sambuc 	0,
193ebfedea0SLionel Sambuc 	ETYPE_ARCFOUR_HMAC_MD5, 16,
194ebfedea0SLionel Sambuc 	NULL,
195ebfedea0SLionel Sambuc 	"\x0c\xb6\x94\x88\x05\xf7\x97\xbf\x2a\x82\x80\x79\x73\xb8\x95\x37"
196ebfedea0SLionel Sambuc     }
197ebfedea0SLionel Sambuc };
198ebfedea0SLionel Sambuc 
199ebfedea0SLionel Sambuc static int
string_to_key_test(krb5_context context)200ebfedea0SLionel Sambuc string_to_key_test(krb5_context context)
201ebfedea0SLionel Sambuc {
202ebfedea0SLionel Sambuc     krb5_data password, opaque;
203ebfedea0SLionel Sambuc     krb5_error_code ret;
204ebfedea0SLionel Sambuc     krb5_salt salt;
205ebfedea0SLionel Sambuc     int i, val = 0;
206ebfedea0SLionel Sambuc     char iter[4];
207ebfedea0SLionel Sambuc 
208ebfedea0SLionel Sambuc     for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
209ebfedea0SLionel Sambuc 
210ebfedea0SLionel Sambuc 	password.data = keys[i].password;
211ebfedea0SLionel Sambuc 	password.length = strlen(password.data);
212ebfedea0SLionel Sambuc 
213ebfedea0SLionel Sambuc 	salt.salttype = KRB5_PW_SALT;
214ebfedea0SLionel Sambuc 	salt.saltvalue.data = keys[i].salt;
215ebfedea0SLionel Sambuc 	if (keys[i].saltlen == -1)
216ebfedea0SLionel Sambuc 	    salt.saltvalue.length = strlen(salt.saltvalue.data);
217ebfedea0SLionel Sambuc 	else
218ebfedea0SLionel Sambuc 	    salt.saltvalue.length = keys[i].saltlen;
219ebfedea0SLionel Sambuc 
220ebfedea0SLionel Sambuc 	opaque.data = iter;
221ebfedea0SLionel Sambuc 	opaque.length = sizeof(iter);
222ebfedea0SLionel Sambuc 	_krb5_put_int(iter, keys[i].iterations, 4);
223ebfedea0SLionel Sambuc 
224ebfedea0SLionel Sambuc 	if (keys[i].pbkdf2) {
225ebfedea0SLionel Sambuc 	    unsigned char keyout[32];
226ebfedea0SLionel Sambuc 
227ebfedea0SLionel Sambuc 	    if (keys[i].keylen > sizeof(keyout))
228ebfedea0SLionel Sambuc 		abort();
229ebfedea0SLionel Sambuc 
230ebfedea0SLionel Sambuc 	    PKCS5_PBKDF2_HMAC_SHA1(password.data, password.length,
231ebfedea0SLionel Sambuc 				   salt.saltvalue.data, salt.saltvalue.length,
232ebfedea0SLionel Sambuc 				   keys[i].iterations,
233ebfedea0SLionel Sambuc 				   keys[i].keylen, keyout);
234ebfedea0SLionel Sambuc 
235ebfedea0SLionel Sambuc 	    if (memcmp(keyout, keys[i].pbkdf2, keys[i].keylen) != 0) {
236ebfedea0SLionel Sambuc 		krb5_warnx(context, "%d: pbkdf2", i);
237ebfedea0SLionel Sambuc 		val = 1;
238ebfedea0SLionel Sambuc 		continue;
239ebfedea0SLionel Sambuc 	    }
240ebfedea0SLionel Sambuc 
241ebfedea0SLionel Sambuc 	    if (verbose) {
242ebfedea0SLionel Sambuc 		printf("PBKDF2:\n");
243ebfedea0SLionel Sambuc 		hex_dump_data(keyout, keys[i].keylen);
244ebfedea0SLionel Sambuc 	    }
245ebfedea0SLionel Sambuc 	}
246ebfedea0SLionel Sambuc 
247ebfedea0SLionel Sambuc 	{
248ebfedea0SLionel Sambuc 	    krb5_keyblock key;
249ebfedea0SLionel Sambuc 
250ebfedea0SLionel Sambuc 	    ret = krb5_string_to_key_data_salt_opaque (context,
251ebfedea0SLionel Sambuc 						       keys[i].enctype,
252ebfedea0SLionel Sambuc 						       password,
253ebfedea0SLionel Sambuc 						       salt,
254ebfedea0SLionel Sambuc 						       opaque,
255ebfedea0SLionel Sambuc 						       &key);
256ebfedea0SLionel Sambuc 	    if (ret) {
257ebfedea0SLionel Sambuc 		krb5_warn(context, ret, "%d: string_to_key_data_salt_opaque",
258ebfedea0SLionel Sambuc 			  i);
259ebfedea0SLionel Sambuc 		val = 1;
260ebfedea0SLionel Sambuc 		continue;
261ebfedea0SLionel Sambuc 	    }
262ebfedea0SLionel Sambuc 
263ebfedea0SLionel Sambuc 	    if (key.keyvalue.length != keys[i].keylen) {
264ebfedea0SLionel Sambuc 		krb5_warnx(context, "%d: key wrong length (%lu/%lu)",
265ebfedea0SLionel Sambuc 			   i, (unsigned long)key.keyvalue.length,
266ebfedea0SLionel Sambuc 			   (unsigned long)keys[i].keylen);
267ebfedea0SLionel Sambuc 		val = 1;
268ebfedea0SLionel Sambuc 		continue;
269ebfedea0SLionel Sambuc 	    }
270ebfedea0SLionel Sambuc 
271ebfedea0SLionel Sambuc 	    if (memcmp(key.keyvalue.data, keys[i].key, keys[i].keylen) != 0) {
272ebfedea0SLionel Sambuc 		krb5_warnx(context, "%d: key wrong", i);
273ebfedea0SLionel Sambuc 		val = 1;
274ebfedea0SLionel Sambuc 		continue;
275ebfedea0SLionel Sambuc 	    }
276ebfedea0SLionel Sambuc 
277ebfedea0SLionel Sambuc 	    if (verbose) {
278ebfedea0SLionel Sambuc 		printf("key:\n");
279ebfedea0SLionel Sambuc 		hex_dump_data(key.keyvalue.data, key.keyvalue.length);
280ebfedea0SLionel Sambuc 	    }
281ebfedea0SLionel Sambuc 	    krb5_free_keyblock_contents(context, &key);
282ebfedea0SLionel Sambuc 	}
283ebfedea0SLionel Sambuc     }
284ebfedea0SLionel Sambuc     return val;
285ebfedea0SLionel Sambuc }
286ebfedea0SLionel Sambuc 
287ebfedea0SLionel Sambuc static int
krb_enc(krb5_context context,krb5_crypto crypto,unsigned usage,krb5_data * cipher,krb5_data * clear)288ebfedea0SLionel Sambuc krb_enc(krb5_context context,
289ebfedea0SLionel Sambuc 	krb5_crypto crypto,
290ebfedea0SLionel Sambuc 	unsigned usage,
291ebfedea0SLionel Sambuc 	krb5_data *cipher,
292ebfedea0SLionel Sambuc 	krb5_data *clear)
293ebfedea0SLionel Sambuc {
294ebfedea0SLionel Sambuc     krb5_data decrypt;
295ebfedea0SLionel Sambuc     krb5_error_code ret;
296ebfedea0SLionel Sambuc 
297ebfedea0SLionel Sambuc     krb5_data_zero(&decrypt);
298ebfedea0SLionel Sambuc 
299ebfedea0SLionel Sambuc     ret = krb5_decrypt(context,
300ebfedea0SLionel Sambuc 		       crypto,
301ebfedea0SLionel Sambuc 		       usage,
302ebfedea0SLionel Sambuc 		       cipher->data,
303ebfedea0SLionel Sambuc 		       cipher->length,
304ebfedea0SLionel Sambuc 		       &decrypt);
305ebfedea0SLionel Sambuc 
306ebfedea0SLionel Sambuc     if (ret) {
307ebfedea0SLionel Sambuc 	krb5_warn(context, ret, "krb5_decrypt");
308ebfedea0SLionel Sambuc 	return ret;
309ebfedea0SLionel Sambuc     }
310ebfedea0SLionel Sambuc 
311ebfedea0SLionel Sambuc     if (decrypt.length != clear->length ||
312ebfedea0SLionel Sambuc 	memcmp(decrypt.data, clear->data, decrypt.length) != 0) {
313ebfedea0SLionel Sambuc 	krb5_warnx(context, "clear text not same");
314ebfedea0SLionel Sambuc 	return EINVAL;
315ebfedea0SLionel Sambuc     }
316ebfedea0SLionel Sambuc 
317ebfedea0SLionel Sambuc     krb5_data_free(&decrypt);
318ebfedea0SLionel Sambuc 
319ebfedea0SLionel Sambuc     return 0;
320ebfedea0SLionel Sambuc }
321ebfedea0SLionel Sambuc 
322ebfedea0SLionel Sambuc static int
krb_enc_iov2(krb5_context context,krb5_crypto crypto,unsigned usage,size_t cipher_len,krb5_data * clear)323ebfedea0SLionel Sambuc krb_enc_iov2(krb5_context context,
324ebfedea0SLionel Sambuc 	     krb5_crypto crypto,
325ebfedea0SLionel Sambuc 	     unsigned usage,
326ebfedea0SLionel Sambuc 	     size_t cipher_len,
327ebfedea0SLionel Sambuc 	     krb5_data *clear)
328ebfedea0SLionel Sambuc {
329ebfedea0SLionel Sambuc     krb5_crypto_iov iov[4];
330ebfedea0SLionel Sambuc     krb5_data decrypt;
331ebfedea0SLionel Sambuc     int ret;
332ebfedea0SLionel Sambuc     char *p, *q;
333ebfedea0SLionel Sambuc     size_t len, i;
334ebfedea0SLionel Sambuc 
335ebfedea0SLionel Sambuc     p = clear->data;
336ebfedea0SLionel Sambuc     len = clear->length;
337ebfedea0SLionel Sambuc 
338ebfedea0SLionel Sambuc     iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
339ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
340ebfedea0SLionel Sambuc     iov[0].data.data = emalloc(iov[0].data.length);
341ebfedea0SLionel Sambuc 
342ebfedea0SLionel Sambuc     iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
343ebfedea0SLionel Sambuc     iov[1].data.length = len;
344ebfedea0SLionel Sambuc     iov[1].data.data = emalloc(iov[1].data.length);
345ebfedea0SLionel Sambuc     memcpy(iov[1].data.data, p, iov[1].data.length);
346ebfedea0SLionel Sambuc 
347ebfedea0SLionel Sambuc     /* padding buffer */
348ebfedea0SLionel Sambuc     iov[2].flags = KRB5_CRYPTO_TYPE_PADDING;
349ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_PADDING, &iov[2].data.length);
350ebfedea0SLionel Sambuc     iov[2].data.data = emalloc(iov[2].data.length);
351ebfedea0SLionel Sambuc 
352ebfedea0SLionel Sambuc     iov[3].flags = KRB5_CRYPTO_TYPE_TRAILER;
353ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[3].flags, &iov[3].data.length);
354ebfedea0SLionel Sambuc     iov[3].data.data = emalloc(iov[3].data.length);
355ebfedea0SLionel Sambuc 
356ebfedea0SLionel Sambuc     ret = krb5_encrypt_iov_ivec(context, crypto, usage,
357ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
358ebfedea0SLionel Sambuc     if (ret)
359ebfedea0SLionel Sambuc 	errx(1, "encrypt iov failed: %d", ret);
360ebfedea0SLionel Sambuc 
361ebfedea0SLionel Sambuc     /* check len */
362ebfedea0SLionel Sambuc     for (i = 0, len = 0; i < sizeof(iov)/sizeof(iov[0]); i++)
363ebfedea0SLionel Sambuc 	len += iov[i].data.length;
364ebfedea0SLionel Sambuc     if (len != cipher_len)
365ebfedea0SLionel Sambuc 	errx(1, "cipher len wrong");
366ebfedea0SLionel Sambuc 
367ebfedea0SLionel Sambuc     /*
368ebfedea0SLionel Sambuc      * Plain decrypt
369ebfedea0SLionel Sambuc      */
370ebfedea0SLionel Sambuc 
371ebfedea0SLionel Sambuc     p = q = emalloc(len);
372ebfedea0SLionel Sambuc     for (i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
373ebfedea0SLionel Sambuc 	memcpy(q, iov[i].data.data, iov[i].data.length);
374ebfedea0SLionel Sambuc 	q += iov[i].data.length;
375ebfedea0SLionel Sambuc     }
376ebfedea0SLionel Sambuc 
377ebfedea0SLionel Sambuc     ret = krb5_decrypt(context, crypto, usage, p, len, &decrypt);
378ebfedea0SLionel Sambuc     if (ret)
379ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_decrypt");
380ebfedea0SLionel Sambuc     else
381ebfedea0SLionel Sambuc 	krb5_data_free(&decrypt);
382ebfedea0SLionel Sambuc 
383ebfedea0SLionel Sambuc     free(p);
384ebfedea0SLionel Sambuc 
385ebfedea0SLionel Sambuc     /*
386ebfedea0SLionel Sambuc      * Now decrypt use iov
387ebfedea0SLionel Sambuc      */
388ebfedea0SLionel Sambuc 
389ebfedea0SLionel Sambuc     /* padding turn into data */
390ebfedea0SLionel Sambuc     p = q = emalloc(iov[1].data.length + iov[2].data.length);
391ebfedea0SLionel Sambuc 
392ebfedea0SLionel Sambuc     memcpy(q, iov[1].data.data, iov[1].data.length);
393ebfedea0SLionel Sambuc     q += iov[1].data.length;
394ebfedea0SLionel Sambuc     memcpy(q, iov[2].data.data, iov[2].data.length);
395ebfedea0SLionel Sambuc 
396ebfedea0SLionel Sambuc     free(iov[1].data.data);
397ebfedea0SLionel Sambuc     free(iov[2].data.data);
398ebfedea0SLionel Sambuc 
399ebfedea0SLionel Sambuc     iov[1].data.data = p;
400ebfedea0SLionel Sambuc     iov[1].data.length += iov[2].data.length;
401ebfedea0SLionel Sambuc 
402ebfedea0SLionel Sambuc     iov[2].flags = KRB5_CRYPTO_TYPE_EMPTY;
403ebfedea0SLionel Sambuc     iov[2].data.length = 0;
404ebfedea0SLionel Sambuc 
405ebfedea0SLionel Sambuc     ret = krb5_decrypt_iov_ivec(context, crypto, usage,
406ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
407ebfedea0SLionel Sambuc     free(iov[0].data.data);
408ebfedea0SLionel Sambuc     free(iov[3].data.data);
409ebfedea0SLionel Sambuc 
410ebfedea0SLionel Sambuc     if (ret)
411ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "decrypt iov failed: %d", ret);
412ebfedea0SLionel Sambuc 
413ebfedea0SLionel Sambuc     if (clear->length != iov[1].data.length)
414ebfedea0SLionel Sambuc 	errx(1, "length incorrect");
415ebfedea0SLionel Sambuc 
416ebfedea0SLionel Sambuc     p = clear->data;
417ebfedea0SLionel Sambuc     if (memcmp(iov[1].data.data, p, iov[1].data.length) != 0)
418ebfedea0SLionel Sambuc 	errx(1, "iov[1] incorrect");
419ebfedea0SLionel Sambuc 
420ebfedea0SLionel Sambuc     free(iov[1].data.data);
421ebfedea0SLionel Sambuc 
422ebfedea0SLionel Sambuc     return 0;
423ebfedea0SLionel Sambuc }
424ebfedea0SLionel Sambuc 
425ebfedea0SLionel Sambuc 
426ebfedea0SLionel Sambuc static int
krb_enc_iov(krb5_context context,krb5_crypto crypto,unsigned usage,krb5_data * cipher,krb5_data * clear)427ebfedea0SLionel Sambuc krb_enc_iov(krb5_context context,
428ebfedea0SLionel Sambuc 	    krb5_crypto crypto,
429ebfedea0SLionel Sambuc 	    unsigned usage,
430ebfedea0SLionel Sambuc 	    krb5_data *cipher,
431ebfedea0SLionel Sambuc 	    krb5_data *clear)
432ebfedea0SLionel Sambuc {
433ebfedea0SLionel Sambuc     krb5_crypto_iov iov[3];
434ebfedea0SLionel Sambuc     int ret;
435ebfedea0SLionel Sambuc     char *p;
436ebfedea0SLionel Sambuc     size_t len;
437ebfedea0SLionel Sambuc 
438ebfedea0SLionel Sambuc     p = cipher->data;
439ebfedea0SLionel Sambuc     len = cipher->length;
440ebfedea0SLionel Sambuc 
441ebfedea0SLionel Sambuc     iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
442ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
443ebfedea0SLionel Sambuc     iov[0].data.data = emalloc(iov[0].data.length);
444ebfedea0SLionel Sambuc     memcpy(iov[0].data.data, p, iov[0].data.length);
445ebfedea0SLionel Sambuc     p += iov[0].data.length;
446ebfedea0SLionel Sambuc     len -= iov[0].data.length;
447ebfedea0SLionel Sambuc 
448ebfedea0SLionel Sambuc     iov[1].flags = KRB5_CRYPTO_TYPE_TRAILER;
449ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[1].flags, &iov[1].data.length);
450ebfedea0SLionel Sambuc     iov[1].data.data = emalloc(iov[1].data.length);
451ebfedea0SLionel Sambuc     memcpy(iov[1].data.data, p + len - iov[1].data.length, iov[1].data.length);
452ebfedea0SLionel Sambuc     len -= iov[1].data.length;
453ebfedea0SLionel Sambuc 
454ebfedea0SLionel Sambuc     iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
455ebfedea0SLionel Sambuc     iov[2].data.length = len;
456ebfedea0SLionel Sambuc     iov[2].data.data = emalloc(len);
457ebfedea0SLionel Sambuc     memcpy(iov[2].data.data, p, len);
458ebfedea0SLionel Sambuc 
459ebfedea0SLionel Sambuc     ret = krb5_decrypt_iov_ivec(context, crypto, usage,
460ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
461ebfedea0SLionel Sambuc     if (ret)
462ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb_enc_iov decrypt iov failed: %d", ret);
463ebfedea0SLionel Sambuc 
464ebfedea0SLionel Sambuc     if (clear->length != iov[2].data.length)
465ebfedea0SLionel Sambuc 	errx(1, "length incorrect");
466ebfedea0SLionel Sambuc 
467ebfedea0SLionel Sambuc     p = clear->data;
468ebfedea0SLionel Sambuc     if (memcmp(iov[2].data.data, p, iov[2].data.length) != 0)
469ebfedea0SLionel Sambuc 	errx(1, "iov[2] incorrect");
470ebfedea0SLionel Sambuc 
471ebfedea0SLionel Sambuc     free(iov[0].data.data);
472ebfedea0SLionel Sambuc     free(iov[1].data.data);
473ebfedea0SLionel Sambuc     free(iov[2].data.data);
474ebfedea0SLionel Sambuc 
475ebfedea0SLionel Sambuc 
476ebfedea0SLionel Sambuc     return 0;
477ebfedea0SLionel Sambuc }
478ebfedea0SLionel Sambuc 
479ebfedea0SLionel Sambuc static int
krb_checksum_iov(krb5_context context,krb5_crypto crypto,unsigned usage,krb5_data * plain)480ebfedea0SLionel Sambuc krb_checksum_iov(krb5_context context,
481ebfedea0SLionel Sambuc 		 krb5_crypto crypto,
482ebfedea0SLionel Sambuc 		 unsigned usage,
483ebfedea0SLionel Sambuc 		 krb5_data *plain)
484ebfedea0SLionel Sambuc {
485ebfedea0SLionel Sambuc     krb5_crypto_iov iov[4];
486ebfedea0SLionel Sambuc     int ret;
487ebfedea0SLionel Sambuc     char *p;
488ebfedea0SLionel Sambuc     size_t len;
489ebfedea0SLionel Sambuc 
490ebfedea0SLionel Sambuc     p = plain->data;
491ebfedea0SLionel Sambuc     len = plain->length;
492ebfedea0SLionel Sambuc 
493ebfedea0SLionel Sambuc     iov[0].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
494ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[0].flags, &iov[0].data.length);
495ebfedea0SLionel Sambuc     iov[0].data.data = emalloc(iov[0].data.length);
496ebfedea0SLionel Sambuc 
497ebfedea0SLionel Sambuc     iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
498ebfedea0SLionel Sambuc     iov[1].data.length = len;
499ebfedea0SLionel Sambuc     iov[1].data.data = p;
500ebfedea0SLionel Sambuc 
501ebfedea0SLionel Sambuc     iov[2].flags = KRB5_CRYPTO_TYPE_TRAILER;
502ebfedea0SLionel Sambuc     krb5_crypto_length(context, crypto, iov[0].flags, &iov[2].data.length);
503ebfedea0SLionel Sambuc     iov[2].data.data = malloc(iov[2].data.length);
504ebfedea0SLionel Sambuc 
505ebfedea0SLionel Sambuc     ret = krb5_create_checksum_iov(context, crypto, usage,
506ebfedea0SLionel Sambuc 				   iov, sizeof(iov)/sizeof(iov[0]), NULL);
507ebfedea0SLionel Sambuc     if (ret)
508ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_create_checksum_iov failed");
509ebfedea0SLionel Sambuc 
510ebfedea0SLionel Sambuc     ret = krb5_verify_checksum_iov(context, crypto, usage, iov, sizeof(iov)/sizeof(iov[0]), NULL);
511ebfedea0SLionel Sambuc     if (ret)
512ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_verify_checksum_iov");
513ebfedea0SLionel Sambuc 
514ebfedea0SLionel Sambuc     free(iov[0].data.data);
515ebfedea0SLionel Sambuc     free(iov[2].data.data);
516ebfedea0SLionel Sambuc 
517ebfedea0SLionel Sambuc     return 0;
518ebfedea0SLionel Sambuc }
519ebfedea0SLionel Sambuc 
520ebfedea0SLionel Sambuc 
521ebfedea0SLionel Sambuc static int
krb_enc_mit(krb5_context context,krb5_enctype enctype,krb5_keyblock * key,unsigned usage,krb5_data * cipher,krb5_data * clear)522ebfedea0SLionel Sambuc krb_enc_mit(krb5_context context,
523ebfedea0SLionel Sambuc 	    krb5_enctype enctype,
524ebfedea0SLionel Sambuc 	    krb5_keyblock *key,
525ebfedea0SLionel Sambuc 	    unsigned usage,
526ebfedea0SLionel Sambuc 	    krb5_data *cipher,
527ebfedea0SLionel Sambuc 	    krb5_data *clear)
528ebfedea0SLionel Sambuc {
529ebfedea0SLionel Sambuc #ifndef HEIMDAL_SMALLER
530ebfedea0SLionel Sambuc     krb5_error_code ret;
531ebfedea0SLionel Sambuc     krb5_enc_data e;
532ebfedea0SLionel Sambuc     krb5_data decrypt;
533ebfedea0SLionel Sambuc     size_t len;
534ebfedea0SLionel Sambuc 
535ebfedea0SLionel Sambuc     e.kvno = 0;
536ebfedea0SLionel Sambuc     e.enctype = enctype;
537ebfedea0SLionel Sambuc     e.ciphertext = *cipher;
538ebfedea0SLionel Sambuc 
539ebfedea0SLionel Sambuc     ret = krb5_c_decrypt(context, *key, usage, NULL, &e, &decrypt);
540ebfedea0SLionel Sambuc     if (ret)
541ebfedea0SLionel Sambuc 	return ret;
542ebfedea0SLionel Sambuc 
543ebfedea0SLionel Sambuc     if (decrypt.length != clear->length ||
544ebfedea0SLionel Sambuc 	memcmp(decrypt.data, clear->data, decrypt.length) != 0) {
545ebfedea0SLionel Sambuc 	krb5_warnx(context, "clear text not same");
546ebfedea0SLionel Sambuc 	return EINVAL;
547ebfedea0SLionel Sambuc     }
548ebfedea0SLionel Sambuc 
549ebfedea0SLionel Sambuc     krb5_data_free(&decrypt);
550ebfedea0SLionel Sambuc 
551ebfedea0SLionel Sambuc     ret = krb5_c_encrypt_length(context, enctype, clear->length, &len);
552ebfedea0SLionel Sambuc     if (ret)
553ebfedea0SLionel Sambuc 	return ret;
554ebfedea0SLionel Sambuc 
555ebfedea0SLionel Sambuc     if (len != cipher->length) {
556ebfedea0SLionel Sambuc 	krb5_warnx(context, "c_encrypt_length wrong %lu != %lu",
557ebfedea0SLionel Sambuc 		   (unsigned long)len, (unsigned long)cipher->length);
558ebfedea0SLionel Sambuc 	return EINVAL;
559ebfedea0SLionel Sambuc     }
560ebfedea0SLionel Sambuc #endif /* HEIMDAL_SMALLER */
561ebfedea0SLionel Sambuc     return 0;
562ebfedea0SLionel Sambuc }
563ebfedea0SLionel Sambuc 
564ebfedea0SLionel Sambuc 
565ebfedea0SLionel Sambuc struct {
566ebfedea0SLionel Sambuc     krb5_enctype enctype;
567ebfedea0SLionel Sambuc     unsigned usage;
568ebfedea0SLionel Sambuc     size_t keylen;
569ebfedea0SLionel Sambuc     void *key;
570ebfedea0SLionel Sambuc     size_t elen;
571ebfedea0SLionel Sambuc     void* edata;
572ebfedea0SLionel Sambuc     size_t plen;
573ebfedea0SLionel Sambuc     void *pdata;
574ebfedea0SLionel Sambuc } krbencs[] =  {
575ebfedea0SLionel Sambuc     {
576ebfedea0SLionel Sambuc 	ETYPE_AES256_CTS_HMAC_SHA1_96,
577ebfedea0SLionel Sambuc 	7,
578ebfedea0SLionel Sambuc 	32,
579ebfedea0SLionel Sambuc 	"\x47\x75\x69\x64\x65\x6c\x69\x6e\x65\x73\x20\x74\x6f\x20\x41\x75"
580ebfedea0SLionel Sambuc 	"\x74\x68\x6f\x72\x73\x20\x6f\x66\x20\x49\x6e\x74\x65\x72\x6e\x65",
581ebfedea0SLionel Sambuc 	44,
582ebfedea0SLionel Sambuc 	"\xcf\x79\x8f\x0d\x76\xf3\xe0\xbe\x8e\x66\x94\x70\xfa\xcc\x9e\x91"
583ebfedea0SLionel Sambuc 	"\xa9\xec\x1c\x5c\x21\xfb\x6e\xef\x1a\x7a\xc8\xc1\xcc\x5a\x95\x24"
584ebfedea0SLionel Sambuc 	"\x6f\x9f\xf4\xd5\xbe\x5d\x59\x97\x44\xd8\x47\xcd",
585ebfedea0SLionel Sambuc 	16,
586ebfedea0SLionel Sambuc 	"\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x2e\x0a"
587ebfedea0SLionel Sambuc     }
588ebfedea0SLionel Sambuc };
589ebfedea0SLionel Sambuc 
590ebfedea0SLionel Sambuc 
591ebfedea0SLionel Sambuc static int
krb_enc_test(krb5_context context)592ebfedea0SLionel Sambuc krb_enc_test(krb5_context context)
593ebfedea0SLionel Sambuc {
594ebfedea0SLionel Sambuc     krb5_error_code ret;
595ebfedea0SLionel Sambuc     krb5_crypto crypto;
596ebfedea0SLionel Sambuc     krb5_keyblock kb;
597ebfedea0SLionel Sambuc     krb5_data cipher, plain;
598ebfedea0SLionel Sambuc     int i;
599ebfedea0SLionel Sambuc 
600ebfedea0SLionel Sambuc     for (i = 0; i < sizeof(krbencs)/sizeof(krbencs[0]); i++) {
601ebfedea0SLionel Sambuc 
602ebfedea0SLionel Sambuc 	kb.keytype = krbencs[i].enctype;
603ebfedea0SLionel Sambuc 	kb.keyvalue.length = krbencs[i].keylen;
604ebfedea0SLionel Sambuc 	kb.keyvalue.data = krbencs[i].key;
605ebfedea0SLionel Sambuc 
606ebfedea0SLionel Sambuc 	ret = krb5_crypto_init(context, &kb, krbencs[i].enctype, &crypto);
607ebfedea0SLionel Sambuc 
608ebfedea0SLionel Sambuc 	cipher.length = krbencs[i].elen;
609ebfedea0SLionel Sambuc 	cipher.data = krbencs[i].edata;
610ebfedea0SLionel Sambuc 	plain.length = krbencs[i].plen;
611ebfedea0SLionel Sambuc 	plain.data = krbencs[i].pdata;
612ebfedea0SLionel Sambuc 
613ebfedea0SLionel Sambuc 	ret = krb_enc(context, crypto, krbencs[i].usage, &cipher, &plain);
614ebfedea0SLionel Sambuc 
615ebfedea0SLionel Sambuc 	if (ret)
616ebfedea0SLionel Sambuc 	    errx(1, "krb_enc failed with %d for test %d", ret, i);
617ebfedea0SLionel Sambuc 
618ebfedea0SLionel Sambuc 	ret = krb_enc_iov(context, crypto, krbencs[i].usage, &cipher, &plain);
619ebfedea0SLionel Sambuc 	if (ret)
620ebfedea0SLionel Sambuc 	    errx(1, "krb_enc_iov failed with %d for test %d", ret, i);
621ebfedea0SLionel Sambuc 
622ebfedea0SLionel Sambuc 	ret = krb_enc_iov2(context, crypto, krbencs[i].usage,
623ebfedea0SLionel Sambuc 			   cipher.length, &plain);
624ebfedea0SLionel Sambuc 	if (ret)
625ebfedea0SLionel Sambuc 	    errx(1, "krb_enc_iov2 failed with %d for test %d", ret, i);
626ebfedea0SLionel Sambuc 
627ebfedea0SLionel Sambuc 	ret = krb_checksum_iov(context, crypto, krbencs[i].usage, &plain);
628ebfedea0SLionel Sambuc 	if (ret)
629ebfedea0SLionel Sambuc 	    errx(1, "krb_checksum_iov failed with %d for test %d", ret, i);
630ebfedea0SLionel Sambuc 
631ebfedea0SLionel Sambuc 	krb5_crypto_destroy(context, crypto);
632ebfedea0SLionel Sambuc 
633ebfedea0SLionel Sambuc 	ret = krb_enc_mit(context, krbencs[i].enctype, &kb,
634ebfedea0SLionel Sambuc 			  krbencs[i].usage, &cipher, &plain);
635ebfedea0SLionel Sambuc 	if (ret)
636ebfedea0SLionel Sambuc 	    errx(1, "krb_enc_mit failed with %d for test %d", ret, i);
637ebfedea0SLionel Sambuc     }
638ebfedea0SLionel Sambuc 
639ebfedea0SLionel Sambuc     return 0;
640ebfedea0SLionel Sambuc }
641ebfedea0SLionel Sambuc 
642ebfedea0SLionel Sambuc static int
iov_test(krb5_context context)643ebfedea0SLionel Sambuc iov_test(krb5_context context)
644ebfedea0SLionel Sambuc {
645ebfedea0SLionel Sambuc     krb5_enctype enctype = ENCTYPE_AES256_CTS_HMAC_SHA1_96;
646ebfedea0SLionel Sambuc     krb5_error_code ret;
647ebfedea0SLionel Sambuc     krb5_crypto crypto;
648ebfedea0SLionel Sambuc     krb5_keyblock key;
649ebfedea0SLionel Sambuc     krb5_data signonly, in, in2;
650ebfedea0SLionel Sambuc     krb5_crypto_iov iov[6];
651ebfedea0SLionel Sambuc     size_t len, i;
652ebfedea0SLionel Sambuc     unsigned char *base, *p;
653ebfedea0SLionel Sambuc 
654ebfedea0SLionel Sambuc     ret = krb5_generate_random_keyblock(context, enctype, &key);
655ebfedea0SLionel Sambuc     if (ret)
656ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
657ebfedea0SLionel Sambuc 
658ebfedea0SLionel Sambuc     ret = krb5_crypto_init(context, &key, 0, &crypto);
659ebfedea0SLionel Sambuc     if (ret)
660ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_crypto_init");
661ebfedea0SLionel Sambuc 
662ebfedea0SLionel Sambuc 
663ebfedea0SLionel Sambuc     ret = krb5_crypto_length(context, crypto, KRB5_CRYPTO_TYPE_HEADER, &len);
664ebfedea0SLionel Sambuc     if (ret)
665ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_crypto_length");
666ebfedea0SLionel Sambuc 
667ebfedea0SLionel Sambuc     signonly.data = "This should be signed";
668ebfedea0SLionel Sambuc     signonly.length = strlen(signonly.data);
669ebfedea0SLionel Sambuc     in.data = "inputdata";
670ebfedea0SLionel Sambuc     in.length = strlen(in.data);
671ebfedea0SLionel Sambuc 
672ebfedea0SLionel Sambuc     in2.data = "INPUTDATA";
673ebfedea0SLionel Sambuc     in2.length = strlen(in2.data);
674ebfedea0SLionel Sambuc 
675ebfedea0SLionel Sambuc 
676ebfedea0SLionel Sambuc     memset(iov, 0, sizeof(iov));
677ebfedea0SLionel Sambuc 
678ebfedea0SLionel Sambuc     iov[0].flags = KRB5_CRYPTO_TYPE_HEADER;
679ebfedea0SLionel Sambuc     iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
680ebfedea0SLionel Sambuc     iov[1].data = in;
681ebfedea0SLionel Sambuc     iov[2].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
682ebfedea0SLionel Sambuc     iov[2].data = signonly;
683ebfedea0SLionel Sambuc     iov[3].flags = KRB5_CRYPTO_TYPE_EMPTY;
684ebfedea0SLionel Sambuc     iov[4].flags = KRB5_CRYPTO_TYPE_PADDING;
685ebfedea0SLionel Sambuc     iov[5].flags = KRB5_CRYPTO_TYPE_TRAILER;
686ebfedea0SLionel Sambuc 
687ebfedea0SLionel Sambuc     ret = krb5_crypto_length_iov(context, crypto, iov,
688ebfedea0SLionel Sambuc 				 sizeof(iov)/sizeof(iov[0]));
689ebfedea0SLionel Sambuc     if (ret)
690ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_crypto_length_iov");
691ebfedea0SLionel Sambuc 
692ebfedea0SLionel Sambuc     for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
693ebfedea0SLionel Sambuc 	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
694ebfedea0SLionel Sambuc 	    continue;
695ebfedea0SLionel Sambuc 	len += iov[i].data.length;
696ebfedea0SLionel Sambuc     }
697ebfedea0SLionel Sambuc 
698ebfedea0SLionel Sambuc     base = emalloc(len);
699ebfedea0SLionel Sambuc 
700ebfedea0SLionel Sambuc     /*
701ebfedea0SLionel Sambuc      * Allocate data for the fields
702ebfedea0SLionel Sambuc      */
703ebfedea0SLionel Sambuc 
704ebfedea0SLionel Sambuc     for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
705ebfedea0SLionel Sambuc 	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
706ebfedea0SLionel Sambuc 	    continue;;
707ebfedea0SLionel Sambuc 	iov[i].data.data = p;
708ebfedea0SLionel Sambuc 	p += iov[i].data.length;
709ebfedea0SLionel Sambuc     }
710ebfedea0SLionel Sambuc     assert(iov[1].data.length == in.length);
711ebfedea0SLionel Sambuc     memcpy(iov[1].data.data, in.data, iov[1].data.length);
712ebfedea0SLionel Sambuc 
713ebfedea0SLionel Sambuc     /*
714ebfedea0SLionel Sambuc      * Encrypt
715ebfedea0SLionel Sambuc      */
716ebfedea0SLionel Sambuc 
717ebfedea0SLionel Sambuc     ret = krb5_encrypt_iov_ivec(context, crypto, 7, iov,
718ebfedea0SLionel Sambuc 				sizeof(iov)/sizeof(iov[0]), NULL);
719ebfedea0SLionel Sambuc     if (ret)
720ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec");
721ebfedea0SLionel Sambuc 
722ebfedea0SLionel Sambuc     /*
723ebfedea0SLionel Sambuc      * Decrypt
724ebfedea0SLionel Sambuc      */
725ebfedea0SLionel Sambuc 
726ebfedea0SLionel Sambuc     ret = krb5_decrypt_iov_ivec(context, crypto, 7,
727ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
728ebfedea0SLionel Sambuc     if (ret)
729ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec");
730ebfedea0SLionel Sambuc 
731ebfedea0SLionel Sambuc     /*
732ebfedea0SLionel Sambuc      * Verify data
733ebfedea0SLionel Sambuc      */
734ebfedea0SLionel Sambuc 
735ebfedea0SLionel Sambuc     if (krb5_data_cmp(&iov[1].data, &in) != 0)
736ebfedea0SLionel Sambuc 	krb5_errx(context, 1, "decrypted data not same");
737ebfedea0SLionel Sambuc 
738ebfedea0SLionel Sambuc     /*
739ebfedea0SLionel Sambuc      * Free memory
740ebfedea0SLionel Sambuc      */
741ebfedea0SLionel Sambuc 
742ebfedea0SLionel Sambuc     free(base);
743ebfedea0SLionel Sambuc 
744ebfedea0SLionel Sambuc     /* Set up for second try */
745ebfedea0SLionel Sambuc 
746ebfedea0SLionel Sambuc     iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
747ebfedea0SLionel Sambuc     iov[3].data = in;
748ebfedea0SLionel Sambuc 
749ebfedea0SLionel Sambuc     ret = krb5_crypto_length_iov(context, crypto,
750ebfedea0SLionel Sambuc 				 iov, sizeof(iov)/sizeof(iov[0]));
751ebfedea0SLionel Sambuc     if (ret)
752ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_crypto_length_iov");
753ebfedea0SLionel Sambuc 
754ebfedea0SLionel Sambuc     for (len = 0, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
755ebfedea0SLionel Sambuc 	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
756ebfedea0SLionel Sambuc 	    continue;
757ebfedea0SLionel Sambuc 	len += iov[i].data.length;
758ebfedea0SLionel Sambuc     }
759ebfedea0SLionel Sambuc 
760ebfedea0SLionel Sambuc     base = emalloc(len);
761ebfedea0SLionel Sambuc 
762ebfedea0SLionel Sambuc     /*
763ebfedea0SLionel Sambuc      * Allocate data for the fields
764ebfedea0SLionel Sambuc      */
765ebfedea0SLionel Sambuc 
766ebfedea0SLionel Sambuc     for (p = base, i = 0; i < sizeof(iov)/sizeof(iov[0]); i++) {
767ebfedea0SLionel Sambuc 	if (iov[i].flags == KRB5_CRYPTO_TYPE_SIGN_ONLY)
768ebfedea0SLionel Sambuc 	    continue;;
769ebfedea0SLionel Sambuc 	iov[i].data.data = p;
770ebfedea0SLionel Sambuc 	p += iov[i].data.length;
771ebfedea0SLionel Sambuc     }
772ebfedea0SLionel Sambuc     assert(iov[1].data.length == in.length);
773ebfedea0SLionel Sambuc     memcpy(iov[1].data.data, in.data, iov[1].data.length);
774ebfedea0SLionel Sambuc 
775ebfedea0SLionel Sambuc     assert(iov[3].data.length == in2.length);
776ebfedea0SLionel Sambuc     memcpy(iov[3].data.data, in2.data, iov[3].data.length);
777ebfedea0SLionel Sambuc 
778ebfedea0SLionel Sambuc 
779ebfedea0SLionel Sambuc 
780ebfedea0SLionel Sambuc     /*
781ebfedea0SLionel Sambuc      * Encrypt
782ebfedea0SLionel Sambuc      */
783ebfedea0SLionel Sambuc 
784ebfedea0SLionel Sambuc     ret = krb5_encrypt_iov_ivec(context, crypto, 7,
785ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
786ebfedea0SLionel Sambuc     if (ret)
787ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_encrypt_iov_ivec");
788ebfedea0SLionel Sambuc 
789ebfedea0SLionel Sambuc     /*
790ebfedea0SLionel Sambuc      * Decrypt
791ebfedea0SLionel Sambuc      */
792ebfedea0SLionel Sambuc 
793ebfedea0SLionel Sambuc     ret = krb5_decrypt_iov_ivec(context, crypto, 7,
794ebfedea0SLionel Sambuc 				iov, sizeof(iov)/sizeof(iov[0]), NULL);
795ebfedea0SLionel Sambuc     if (ret)
796ebfedea0SLionel Sambuc 	krb5_err(context, 1, ret, "krb5_decrypt_iov_ivec");
797ebfedea0SLionel Sambuc 
798ebfedea0SLionel Sambuc     /*
799ebfedea0SLionel Sambuc      * Verify data
800ebfedea0SLionel Sambuc      */
801ebfedea0SLionel Sambuc 
802ebfedea0SLionel Sambuc     if (krb5_data_cmp(&iov[1].data, &in) != 0)
803ebfedea0SLionel Sambuc 	krb5_errx(context, 1, "decrypted data 2.1 not same");
804ebfedea0SLionel Sambuc 
805ebfedea0SLionel Sambuc     if (krb5_data_cmp(&iov[3].data, &in2) != 0)
806ebfedea0SLionel Sambuc 	krb5_errx(context, 1, "decrypted data 2.2 not same");
807ebfedea0SLionel Sambuc 
808ebfedea0SLionel Sambuc     /*
809ebfedea0SLionel Sambuc      * Free memory
810ebfedea0SLionel Sambuc      */
811ebfedea0SLionel Sambuc 
812ebfedea0SLionel Sambuc     free(base);
813ebfedea0SLionel Sambuc 
814ebfedea0SLionel Sambuc     krb5_crypto_destroy(context, crypto);
815ebfedea0SLionel Sambuc 
816ebfedea0SLionel Sambuc     krb5_free_keyblock_contents(context, &key);
817ebfedea0SLionel Sambuc 
818ebfedea0SLionel Sambuc     return 0;
819ebfedea0SLionel Sambuc }
820ebfedea0SLionel Sambuc 
821ebfedea0SLionel Sambuc 
822ebfedea0SLionel Sambuc 
823ebfedea0SLionel Sambuc static int
random_to_key(krb5_context context)824ebfedea0SLionel Sambuc random_to_key(krb5_context context)
825ebfedea0SLionel Sambuc {
826ebfedea0SLionel Sambuc     krb5_error_code ret;
827ebfedea0SLionel Sambuc     krb5_keyblock key;
828ebfedea0SLionel Sambuc 
829ebfedea0SLionel Sambuc     ret = krb5_random_to_key(context,
830ebfedea0SLionel Sambuc 			     ETYPE_DES3_CBC_SHA1,
831ebfedea0SLionel Sambuc 			     "\x21\x39\x04\x58\x6A\xBD\x7F"
832ebfedea0SLionel Sambuc 			     "\x21\x39\x04\x58\x6A\xBD\x7F"
833ebfedea0SLionel Sambuc 			     "\x21\x39\x04\x58\x6A\xBD\x7F",
834ebfedea0SLionel Sambuc 			     21,
835ebfedea0SLionel Sambuc 			     &key);
836ebfedea0SLionel Sambuc     if (ret){
837ebfedea0SLionel Sambuc 	krb5_warn(context, ret, "random_to_key");
838ebfedea0SLionel Sambuc 	return 1;
839ebfedea0SLionel Sambuc     }
840ebfedea0SLionel Sambuc     if (key.keyvalue.length != 24)
841ebfedea0SLionel Sambuc 	return 1;
842ebfedea0SLionel Sambuc 
843ebfedea0SLionel Sambuc     if (memcmp(key.keyvalue.data,
844ebfedea0SLionel Sambuc 	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7"
845ebfedea0SLionel Sambuc 	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7"
846ebfedea0SLionel Sambuc 	       "\x20\x38\x04\x58\x6b\xbc\x7f\xc7",
847ebfedea0SLionel Sambuc 	       24) != 0)
848ebfedea0SLionel Sambuc 	return 1;
849ebfedea0SLionel Sambuc 
850ebfedea0SLionel Sambuc     krb5_free_keyblock_contents(context, &key);
851ebfedea0SLionel Sambuc 
852ebfedea0SLionel Sambuc     return 0;
853ebfedea0SLionel Sambuc }
854ebfedea0SLionel Sambuc 
855ebfedea0SLionel Sambuc int
main(int argc,char ** argv)856ebfedea0SLionel Sambuc main(int argc, char **argv)
857ebfedea0SLionel Sambuc {
858ebfedea0SLionel Sambuc     krb5_error_code ret;
859ebfedea0SLionel Sambuc     krb5_context context;
860ebfedea0SLionel Sambuc     int val = 0;
861ebfedea0SLionel Sambuc 
862ebfedea0SLionel Sambuc     ret = krb5_init_context (&context);
863ebfedea0SLionel Sambuc     if (ret)
864ebfedea0SLionel Sambuc 	errx (1, "krb5_init_context failed: %d", ret);
865ebfedea0SLionel Sambuc 
866ebfedea0SLionel Sambuc     val |= string_to_key_test(context);
867ebfedea0SLionel Sambuc 
868ebfedea0SLionel Sambuc     val |= krb_enc_test(context);
869ebfedea0SLionel Sambuc     val |= random_to_key(context);
870ebfedea0SLionel Sambuc     val |= iov_test(context);
871ebfedea0SLionel Sambuc 
872ebfedea0SLionel Sambuc     if (verbose && val == 0)
873ebfedea0SLionel Sambuc 	printf("all ok\n");
874ebfedea0SLionel Sambuc     if (val)
875ebfedea0SLionel Sambuc 	printf("tests failed\n");
876ebfedea0SLionel Sambuc 
877ebfedea0SLionel Sambuc     krb5_free_context(context);
878ebfedea0SLionel Sambuc 
879ebfedea0SLionel Sambuc     return val;
880ebfedea0SLionel Sambuc }
881