9069 libfru: comparison between pointer and zero character constant
[unleashed.git] / usr / src / common / net / wanboot / crypt / des3.c
blob397644f2dccf6bd962c9dcf99d143db5c2eda107
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdlib.h>
30 #include <strings.h>
31 #include <sys/sysmacros.h>
33 #include "des3.h"
34 #include "des.h"
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];
41 uint32_t ksch_decrypt1[16][2];
42 uint32_t ksch_decrypt2[16][2];
43 uint32_t ksch_decrypt3[16][2];
44 } keysched_t;
46 int
47 des3_init(void **cookie)
49 if ((*cookie = malloc(sizeof (keysched_t))) == NULL) {
50 return (-1);
52 return (0);
55 void
56 des3_fini(void *cookie)
58 free(cookie);
61 void
62 des3_encrypt(void *cookie, uint8_t *block)
64 keysched_t *ksch = (keysched_t *)cookie;
66 des(ksch->ksch_encrypt1, block);
67 des(ksch->ksch_decrypt2, block);
68 des(ksch->ksch_encrypt3, block);
71 void
72 des3_decrypt(void *cookie, uint8_t *block)
74 keysched_t *ksch = (keysched_t *)cookie;
76 des(ksch->ksch_decrypt3, block);
77 des(ksch->ksch_encrypt2, block);
78 des(ksch->ksch_decrypt1, block);
82 * Generate key schedule for triple DES in E-D-E (or D-E-D) mode.
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
88 void
89 des3_key(void *cookie, const uint8_t *key)
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;
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);
105 boolean_t
106 des3_keycheck(const uint8_t *key)
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;
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.
123 static uint64_t des_weak_keys[] = {
124 /* Really weak keys. Byte-order independent values. */
125 0x0101010101010101ULL,
126 0x1f1f1f1f0e0e0e0eULL,
127 0xe0e0e0e0f1f1f1f1ULL,
128 0xfefefefefefefefeULL,
130 /* Semi-weak (and a few possibly-weak) keys. */
132 /* Byte-order independent semi-weak keys. */
133 0x01fe01fe01fe01feULL, 0xfe01fe01fe01fe01ULL,
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
150 /* We'll save the other possibly-weak keys for the future. */
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));
161 for (j = 0; j < 3; j++) {
162 key_so_far = currentkey[j];
163 scratch = key_so_far;
165 /* Unroll the loop within each byte. */
166 for (i = 0; i < 8; i++) {
167 parity = 1;
170 * Start shifting at byte n, right to left.
171 * Low bit (0) doesn't count.
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;
196 parity &= 1; /* Mask off other bits. */
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));
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 {
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.
217 * Break from the weak key loop
218 * (since this DES key is weak) and
219 * continue on.
221 break;
227 * Fix key extension, adjust bits if necessary.
229 currentkey[j] = key_so_far;
233 * Perform key equivalence checks, now that parity is properly set.
234 * All three keys must be unique.
236 if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2] ||
237 currentkey[2] == currentkey[0]) {
238 return (B_FALSE);
241 return (B_TRUE);