xref: /titanic_44/usr/src/common/net/wanboot/crypt/des3.c (revision 0dc2366f7b9f9f36e10909b1e95edbf2a261c2ac)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <sys/sysmacros.h>
32 
33 #include "des3.h"
34 #include "des.h"
35 
36 typedef struct keysched_s {
37 	uint32_t ksch_encrypt1[16][2];
38 	uint32_t ksch_encrypt2[16][2];
39 	uint32_t ksch_encrypt3[16][2];
40 
41 	uint32_t ksch_decrypt1[16][2];
42 	uint32_t ksch_decrypt2[16][2];
43 	uint32_t ksch_decrypt3[16][2];
44 } keysched_t;
45 
46 int
47 des3_init(void **cookie)
48 {
49 	if ((*cookie = malloc(sizeof (keysched_t))) == NULL) {
50 		return (-1);
51 	}
52 	return (0);
53 }
54 
55 void
56 des3_fini(void *cookie)
57 {
58 	free(cookie);
59 }
60 
61 void
62 des3_encrypt(void *cookie, uint8_t *block)
63 {
64 	keysched_t *ksch = (keysched_t *)cookie;
65 
66 	des(ksch->ksch_encrypt1, block);
67 	des(ksch->ksch_decrypt2, block);
68 	des(ksch->ksch_encrypt3, block);
69 }
70 
71 void
72 des3_decrypt(void *cookie, uint8_t *block)
73 {
74 	keysched_t *ksch = (keysched_t *)cookie;
75 
76 	des(ksch->ksch_decrypt3, block);
77 	des(ksch->ksch_encrypt2, block);
78 	des(ksch->ksch_decrypt1, block);
79 }
80 
81 /*
82  * Generate key schedule for triple DES in E-D-E (or D-E-D) mode.
83  *
84  * The key argument is taken to be 24 bytes. The first 8 bytes are K1
85  * for the first stage, the second 8 bytes are K2 for the middle stage
86  * and the third 8 bytes are K3 for the last stage
87  */
88 void
89 des3_key(void *cookie, const uint8_t *key)
90 {
91 	keysched_t *ks = (keysched_t *)cookie;
92 	uint8_t *k1 = (uint8_t *)key;
93 	uint8_t *k2 = k1 + DES_KEY_SIZE;
94 	uint8_t *k3 = k2 + DES_KEY_SIZE;
95 
96 	des_key(ks->ksch_decrypt1, k1, B_TRUE);
97 	des_key(ks->ksch_encrypt1, k1, B_FALSE);
98 	des_key(ks->ksch_decrypt2, k2, B_TRUE);
99 	des_key(ks->ksch_encrypt2, k2, B_FALSE);
100 	des_key(ks->ksch_decrypt3, k3, B_TRUE);
101 	des_key(ks->ksch_encrypt3, k3, B_FALSE);
102 }
103 
104 
105 boolean_t
106 des3_keycheck(const uint8_t *key)
107 {
108 	uint64_t key_so_far;
109 	uint64_t scratch;
110 	uint64_t *currentkey;
111 	uint64_t tmpbuf[3];
112 	uint_t parity;
113 	uint_t num_weakkeys = 0;
114 	uint_t i;
115 	uint_t j;
116 
117 	/*
118 	 * Table of weak and semi-weak keys.  Fortunately, weak keys are
119 	 * endian-independent, and some semi-weak keys can be paired up in
120 	 * endian-opposite order.  Since keys are stored as uint64_t's,
121 	 * use the ifdef _LITTLE_ENDIAN where appropriate.
122 	 */
123 	static uint64_t des_weak_keys[] = {
124 		/* Really weak keys.  Byte-order independent values. */
125 		0x0101010101010101ULL,
126 		0x1f1f1f1f0e0e0e0eULL,
127 		0xe0e0e0e0f1f1f1f1ULL,
128 		0xfefefefefefefefeULL,
129 
130 		/* Semi-weak (and a few possibly-weak) keys. */
131 
132 		/* Byte-order independent semi-weak keys. */
133 		0x01fe01fe01fe01feULL,	0xfe01fe01fe01fe01ULL,
134 
135 		/* Byte-order dependent semi-weak keys. */
136 #ifdef _LITTLE_ENDIAN
137 		0xf10ef10ee01fe01fULL,	0x0ef10ef11fe01fe0ULL,
138 		0x01f101f101e001e0ULL,	0xf101f101e001e001ULL,
139 		0x0efe0efe1ffe1ffeULL,	0xfe0efe0efe1ffe1fULL,
140 		0x010e010e011f011fULL,	0x0e010e011f011f01ULL,
141 		0xf1fef1fee0fee0feULL,	0xfef1fef1fee0fee0ULL,
142 #else	/* Big endian */
143 		0x1fe01fe00ef10ef1ULL,	0xe01fe01ff10ef10eULL,
144 		0x01e001e001f101f1ULL,	0xe001e001f101f101ULL,
145 		0x1ffe1ffe0efe0efeULL,	0xfe1ffe1ffe0efe0eULL,
146 		0x011f011f010e010eULL,	0x1f011f010e010e01ULL,
147 		0xe0fee0fef1fef1feULL,	0xfee0fee0fef1fef1ULL,
148 #endif
149 
150 		/* We'll save the other possibly-weak keys for the future. */
151 	};
152 
153 	if (IS_P2ALIGNED(key, sizeof (uint64_t))) {
154 		/* LINTED */
155 		currentkey = (uint64_t *)key;
156 	} else {
157 		currentkey = tmpbuf;
158 		bcopy(key, currentkey, 3 * sizeof (uint64_t));
159 	}
160 
161 	for (j = 0; j < 3; j++) {
162 		key_so_far = currentkey[j];
163 		scratch = key_so_far;
164 
165 		/* Unroll the loop within each byte. */
166 		for (i = 0; i < 8; i++) {
167 			parity = 1;
168 
169 			/*
170 			 * Start shifting at byte n, right to left.
171 			 * Low bit (0) doesn't count.
172 			 */
173 			scratch >>= 1;
174 			if (scratch & 0x1)	/* bit 1 */
175 				parity++;
176 			scratch >>= 1;
177 			if (scratch & 0x1)	/* bit 2 */
178 				parity++;
179 			scratch >>= 1;
180 			if (scratch & 0x1)	/* bit 3 */
181 				parity++;
182 			scratch >>= 1;
183 			if (scratch & 0x1)	/* bit 4 */
184 				parity++;
185 			scratch >>= 1;
186 			if (scratch & 0x1)	/* bit 5 */
187 				parity++;
188 			scratch >>= 1;
189 			if (scratch & 0x1)	/* bit 6 */
190 			parity++;
191 			scratch >>= 1;
192 			if (scratch & 0x1)	/* bit 7 */
193 				parity++;
194 			scratch >>= 1;
195 
196 			parity &= 1;	/* Mask off other bits. */
197 
198 			/* Will common subexpression elimination help me? */
199 			key_so_far &= ~((uint64_t)1 << (i << 3));
200 			key_so_far |= ((uint64_t)parity << (i << 3));
201 		}
202 
203 		/* Do weak key check itself. */
204 		for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t));
205 		    i++) {
206 			if (key_so_far == des_weak_keys[i]) {
207 				/* In 3DES, one weak key is OK.  Two is bad. */
208 				if (++num_weakkeys > 1) {
209 					return (B_FALSE);
210 				} else {
211 					/*
212 					 * We found a weak key, but since
213 					 * we've only found one weak key,
214 					 * we can not reject the whole 3DES
215 					 * set of keys as weak.
216 					 *
217 					 * Break from the weak key loop
218 					 * (since this DES key is weak) and
219 					 * continue on.
220 					 */
221 					break;
222 				}
223 			}
224 		}
225 
226 		/*
227 		 * Fix key extension, adjust bits if necessary.
228 		 */
229 		currentkey[j] = key_so_far;
230 	}
231 
232 	/*
233 	 * Perform key equivalence checks, now that parity is properly set.
234 	 * All three keys must be unique.
235 	 */
236 	if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2] ||
237 	    currentkey[2] == currentkey[0]) {
238 		return (B_FALSE);
239 	}
240 
241 	return (B_TRUE);
242 }
243