10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*485Scarlsonj * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <strings.h>
310Sstevel@tonic-gate #include <sys/sysmacros.h>
320Sstevel@tonic-gate
330Sstevel@tonic-gate #include "des3.h"
340Sstevel@tonic-gate #include "des.h"
350Sstevel@tonic-gate
360Sstevel@tonic-gate typedef struct keysched_s {
370Sstevel@tonic-gate uint32_t ksch_encrypt1[16][2];
380Sstevel@tonic-gate uint32_t ksch_encrypt2[16][2];
390Sstevel@tonic-gate uint32_t ksch_encrypt3[16][2];
400Sstevel@tonic-gate
410Sstevel@tonic-gate uint32_t ksch_decrypt1[16][2];
420Sstevel@tonic-gate uint32_t ksch_decrypt2[16][2];
430Sstevel@tonic-gate uint32_t ksch_decrypt3[16][2];
440Sstevel@tonic-gate } keysched_t;
450Sstevel@tonic-gate
460Sstevel@tonic-gate int
des3_init(void ** cookie)470Sstevel@tonic-gate des3_init(void **cookie)
480Sstevel@tonic-gate {
490Sstevel@tonic-gate if ((*cookie = malloc(sizeof (keysched_t))) == NULL) {
500Sstevel@tonic-gate return (-1);
510Sstevel@tonic-gate }
520Sstevel@tonic-gate return (0);
530Sstevel@tonic-gate }
540Sstevel@tonic-gate
550Sstevel@tonic-gate void
des3_fini(void * cookie)560Sstevel@tonic-gate des3_fini(void *cookie)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate free(cookie);
590Sstevel@tonic-gate }
600Sstevel@tonic-gate
610Sstevel@tonic-gate void
des3_encrypt(void * cookie,uint8_t * block)620Sstevel@tonic-gate des3_encrypt(void *cookie, uint8_t *block)
630Sstevel@tonic-gate {
640Sstevel@tonic-gate keysched_t *ksch = (keysched_t *)cookie;
650Sstevel@tonic-gate
660Sstevel@tonic-gate des(ksch->ksch_encrypt1, block);
670Sstevel@tonic-gate des(ksch->ksch_decrypt2, block);
680Sstevel@tonic-gate des(ksch->ksch_encrypt3, block);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate
710Sstevel@tonic-gate void
des3_decrypt(void * cookie,uint8_t * block)720Sstevel@tonic-gate des3_decrypt(void *cookie, uint8_t *block)
730Sstevel@tonic-gate {
740Sstevel@tonic-gate keysched_t *ksch = (keysched_t *)cookie;
750Sstevel@tonic-gate
760Sstevel@tonic-gate des(ksch->ksch_decrypt3, block);
770Sstevel@tonic-gate des(ksch->ksch_encrypt2, block);
780Sstevel@tonic-gate des(ksch->ksch_decrypt1, block);
790Sstevel@tonic-gate }
800Sstevel@tonic-gate
810Sstevel@tonic-gate /*
820Sstevel@tonic-gate * Generate key schedule for triple DES in E-D-E (or D-E-D) mode.
830Sstevel@tonic-gate *
840Sstevel@tonic-gate * The key argument is taken to be 24 bytes. The first 8 bytes are K1
850Sstevel@tonic-gate * for the first stage, the second 8 bytes are K2 for the middle stage
860Sstevel@tonic-gate * and the third 8 bytes are K3 for the last stage
870Sstevel@tonic-gate */
880Sstevel@tonic-gate void
des3_key(void * cookie,const uint8_t * key)890Sstevel@tonic-gate des3_key(void *cookie, const uint8_t *key)
900Sstevel@tonic-gate {
910Sstevel@tonic-gate keysched_t *ks = (keysched_t *)cookie;
920Sstevel@tonic-gate uint8_t *k1 = (uint8_t *)key;
930Sstevel@tonic-gate uint8_t *k2 = k1 + DES_KEY_SIZE;
940Sstevel@tonic-gate uint8_t *k3 = k2 + DES_KEY_SIZE;
950Sstevel@tonic-gate
960Sstevel@tonic-gate des_key(ks->ksch_decrypt1, k1, B_TRUE);
970Sstevel@tonic-gate des_key(ks->ksch_encrypt1, k1, B_FALSE);
980Sstevel@tonic-gate des_key(ks->ksch_decrypt2, k2, B_TRUE);
990Sstevel@tonic-gate des_key(ks->ksch_encrypt2, k2, B_FALSE);
1000Sstevel@tonic-gate des_key(ks->ksch_decrypt3, k3, B_TRUE);
1010Sstevel@tonic-gate des_key(ks->ksch_encrypt3, k3, B_FALSE);
1020Sstevel@tonic-gate }
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate boolean_t
des3_keycheck(const uint8_t * key)1060Sstevel@tonic-gate des3_keycheck(const uint8_t *key)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate uint64_t key_so_far;
1090Sstevel@tonic-gate uint64_t scratch;
1100Sstevel@tonic-gate uint64_t *currentkey;
1110Sstevel@tonic-gate uint64_t tmpbuf[3];
1120Sstevel@tonic-gate uint_t parity;
1130Sstevel@tonic-gate uint_t num_weakkeys = 0;
1140Sstevel@tonic-gate uint_t i;
1150Sstevel@tonic-gate uint_t j;
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate /*
1180Sstevel@tonic-gate * Table of weak and semi-weak keys. Fortunately, weak keys are
1190Sstevel@tonic-gate * endian-independent, and some semi-weak keys can be paired up in
1200Sstevel@tonic-gate * endian-opposite order. Since keys are stored as uint64_t's,
1210Sstevel@tonic-gate * use the ifdef _LITTLE_ENDIAN where appropriate.
1220Sstevel@tonic-gate */
1230Sstevel@tonic-gate static uint64_t des_weak_keys[] = {
1240Sstevel@tonic-gate /* Really weak keys. Byte-order independent values. */
125*485Scarlsonj 0x0101010101010101ULL,
126*485Scarlsonj 0x1f1f1f1f0e0e0e0eULL,
127*485Scarlsonj 0xe0e0e0e0f1f1f1f1ULL,
128*485Scarlsonj 0xfefefefefefefefeULL,
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate /* Semi-weak (and a few possibly-weak) keys. */
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate /* Byte-order independent semi-weak keys. */
133*485Scarlsonj 0x01fe01fe01fe01feULL, 0xfe01fe01fe01fe01ULL,
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate /* Byte-order dependent semi-weak keys. */
1360Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
137*485Scarlsonj 0xf10ef10ee01fe01fULL, 0x0ef10ef11fe01fe0ULL,
138*485Scarlsonj 0x01f101f101e001e0ULL, 0xf101f101e001e001ULL,
139*485Scarlsonj 0x0efe0efe1ffe1ffeULL, 0xfe0efe0efe1ffe1fULL,
140*485Scarlsonj 0x010e010e011f011fULL, 0x0e010e011f011f01ULL,
141*485Scarlsonj 0xf1fef1fee0fee0feULL, 0xfef1fef1fee0fee0ULL,
1420Sstevel@tonic-gate #else /* Big endian */
143*485Scarlsonj 0x1fe01fe00ef10ef1ULL, 0xe01fe01ff10ef10eULL,
144*485Scarlsonj 0x01e001e001f101f1ULL, 0xe001e001f101f101ULL,
145*485Scarlsonj 0x1ffe1ffe0efe0efeULL, 0xfe1ffe1ffe0efe0eULL,
146*485Scarlsonj 0x011f011f010e010eULL, 0x1f011f010e010e01ULL,
147*485Scarlsonj 0xe0fee0fef1fef1feULL, 0xfee0fee0fef1fef1ULL,
1480Sstevel@tonic-gate #endif
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate /* We'll save the other possibly-weak keys for the future. */
1510Sstevel@tonic-gate };
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate if (IS_P2ALIGNED(key, sizeof (uint64_t))) {
1540Sstevel@tonic-gate /* LINTED */
1550Sstevel@tonic-gate currentkey = (uint64_t *)key;
1560Sstevel@tonic-gate } else {
1570Sstevel@tonic-gate currentkey = tmpbuf;
1580Sstevel@tonic-gate bcopy(key, currentkey, 3 * sizeof (uint64_t));
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate for (j = 0; j < 3; j++) {
1620Sstevel@tonic-gate key_so_far = currentkey[j];
1630Sstevel@tonic-gate scratch = key_so_far;
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate /* Unroll the loop within each byte. */
1660Sstevel@tonic-gate for (i = 0; i < 8; i++) {
1670Sstevel@tonic-gate parity = 1;
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate * Start shifting at byte n, right to left.
1710Sstevel@tonic-gate * Low bit (0) doesn't count.
1720Sstevel@tonic-gate */
1730Sstevel@tonic-gate scratch >>= 1;
1740Sstevel@tonic-gate if (scratch & 0x1) /* bit 1 */
1750Sstevel@tonic-gate parity++;
1760Sstevel@tonic-gate scratch >>= 1;
1770Sstevel@tonic-gate if (scratch & 0x1) /* bit 2 */
1780Sstevel@tonic-gate parity++;
1790Sstevel@tonic-gate scratch >>= 1;
1800Sstevel@tonic-gate if (scratch & 0x1) /* bit 3 */
1810Sstevel@tonic-gate parity++;
1820Sstevel@tonic-gate scratch >>= 1;
1830Sstevel@tonic-gate if (scratch & 0x1) /* bit 4 */
1840Sstevel@tonic-gate parity++;
1850Sstevel@tonic-gate scratch >>= 1;
1860Sstevel@tonic-gate if (scratch & 0x1) /* bit 5 */
1870Sstevel@tonic-gate parity++;
1880Sstevel@tonic-gate scratch >>= 1;
1890Sstevel@tonic-gate if (scratch & 0x1) /* bit 6 */
1900Sstevel@tonic-gate parity++;
1910Sstevel@tonic-gate scratch >>= 1;
1920Sstevel@tonic-gate if (scratch & 0x1) /* bit 7 */
1930Sstevel@tonic-gate parity++;
1940Sstevel@tonic-gate scratch >>= 1;
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate parity &= 1; /* Mask off other bits. */
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate /* Will common subexpression elimination help me? */
1990Sstevel@tonic-gate key_so_far &= ~((uint64_t)1 << (i << 3));
2000Sstevel@tonic-gate key_so_far |= ((uint64_t)parity << (i << 3));
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate /* Do weak key check itself. */
2040Sstevel@tonic-gate for (i = 0; i < (sizeof (des_weak_keys) / sizeof (uint64_t));
2050Sstevel@tonic-gate i++) {
2060Sstevel@tonic-gate if (key_so_far == des_weak_keys[i]) {
2070Sstevel@tonic-gate /* In 3DES, one weak key is OK. Two is bad. */
2080Sstevel@tonic-gate if (++num_weakkeys > 1) {
2090Sstevel@tonic-gate return (B_FALSE);
2100Sstevel@tonic-gate } else {
2110Sstevel@tonic-gate /*
2120Sstevel@tonic-gate * We found a weak key, but since
2130Sstevel@tonic-gate * we've only found one weak key,
2140Sstevel@tonic-gate * we can not reject the whole 3DES
2150Sstevel@tonic-gate * set of keys as weak.
2160Sstevel@tonic-gate *
2170Sstevel@tonic-gate * Break from the weak key loop
2180Sstevel@tonic-gate * (since this DES key is weak) and
2190Sstevel@tonic-gate * continue on.
2200Sstevel@tonic-gate */
2210Sstevel@tonic-gate break;
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate /*
2270Sstevel@tonic-gate * Fix key extension, adjust bits if necessary.
2280Sstevel@tonic-gate */
2290Sstevel@tonic-gate currentkey[j] = key_so_far;
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate /*
2330Sstevel@tonic-gate * Perform key equivalence checks, now that parity is properly set.
2340Sstevel@tonic-gate * All three keys must be unique.
2350Sstevel@tonic-gate */
2360Sstevel@tonic-gate if (currentkey[0] == currentkey[1] || currentkey[1] == currentkey[2] ||
2370Sstevel@tonic-gate currentkey[2] == currentkey[0]) {
2380Sstevel@tonic-gate return (B_FALSE);
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate return (B_TRUE);
2420Sstevel@tonic-gate }
243