diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libcrypt/common/des_crypt.c | |
download | illumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libcrypt/common/des_crypt.c')
-rw-r--r-- | usr/src/lib/libcrypt/common/des_crypt.c | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/usr/src/lib/libcrypt/common/des_crypt.c b/usr/src/lib/libcrypt/common/des_crypt.c new file mode 100644 index 0000000000..b7fd085065 --- /dev/null +++ b/usr/src/lib/libcrypt/common/des_crypt.c @@ -0,0 +1,422 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ + + +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" +/*LINTLIBRARY*/ + +#pragma weak des_crypt = _des_crypt +#pragma weak des_encrypt = _des_encrypt +#pragma weak des_setkey = _des_setkey + +#include "synonyms.h" +#include "mtlib.h" +#include <sys/types.h> +#include <crypt.h> +#include "des_soft.h" + +#include <stdlib.h> +#include <thread.h> +#include <synch.h> +#include <sys/types.h> + +/* EXPORT DELETE START */ +/* + * This program implements the + * Proposed Federal Information Processing + * Data Encryption Standard. + * See Federal Register, March 17, 1975 (40FR12134) + */ + +/* + * Initial permutation, + */ +static char IP[] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, +}; + +/* + * Final permutation, FP = IP^(-1) + */ +static char FP[] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25, +}; + +/* + * Permuted-choice 1 from the key bits + * to yield C and D. + * Note that bits 8, 16... are left out: + * They are intended for a parity check. + */ +static char PC1_C[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, +}; + +static char PC1_D[] = { + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4, +}; + +/* + * Sequence of shifts used for the key schedule. + */ +static char shifts[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, }; + +/* + * Permuted-choice 2, to pick out the bits from + * the CD array that generate the key schedule. + */ +static char PC2_C[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, +}; + +static char PC2_D[] = { + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32, +}; + +/* + * The C and D arrays used to calculate the key schedule. + */ + +static char C[28]; +static char D[28]; +/* + * The key schedule. + * Generated from the key. + */ +static char KS[16][48]; + +/* + * The E bit-selection table. + */ +static char E[48]; +static char e2[] = { + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1, +}; + +/* + * Set up the key schedule from the key. + */ + +static mutex_t lock = DEFAULTMUTEX; + +/* EXPORT DELETE END */ + + +static void +des_setkey_nolock(const char *key) +{ +/* EXPORT DELETE START */ + int i, j, k; + char t; + + /* + * First, generate C and D by permuting + * the key. The low order bit of each + * 8-bit char is not used, so C and D are only 28 + * bits apiece. + */ + for (i = 0; i < 28; i++) { + C[i] = key[PC1_C[i]-1]; + D[i] = key[PC1_D[i]-1]; + } + /* + * To generate Ki, rotate C and D according + * to schedule and pick up a permutation + * using PC2. + */ + for (i = 0; i < 16; i++) { + /* + * rotate. + */ + for (k = 0; k < shifts[i]; k++) { + t = C[0]; + for (j = 0; j < 28-1; j++) + C[j] = C[j+1]; + C[27] = (char)t; + t = D[0]; + for (j = 0; j < 28-1; j++) + D[j] = D[j+1]; + D[27] = (char)t; + } + /* + * get Ki. Note C and D are concatenated. + */ + for (j = 0; j < 24; j++) { + KS[i][j] = C[PC2_C[j]-1]; + KS[i][j+24] = D[PC2_D[j]-28-1]; + } + } + + for (i = 0; i < 48; i++) + E[i] = e2[i]; +/* EXPORT DELETE END */ +} + +void +des_setkey(const char *key) +{ +/* EXPORT DELETE START */ + (void) mutex_lock(&lock); + des_setkey_nolock(key); + (void) mutex_unlock(&lock); +/* EXPORT DELETE END */ +} + +/* EXPORT DELETE START */ +/* + * The 8 selection functions. + * For some reason, they give a 0-origin + * index, unlike everything else. + */ +static char S[8][64] = { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, +}; + +/* + * P is a permutation on the selected combination + * of the current L and key. + */ +static char P[] = { + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25, +}; + +/* + * The current block, divided into 2 halves. + */ +static char L[64]; +static char tempL[32]; +static char f[32]; + +/* + * The combination of the key and the input, before selection. + */ +static char preS[48]; + +/* + * The payoff: encrypt a block. + */ +/* EXPORT DELETE END */ + +static void +des_encrypt_nolock(char *block, int edflag) +{ +/* EXPORT DELETE START */ + + if (edflag) + (void) des_decrypt1(block, L, IP, &L[32], + preS, E, KS, S, f, tempL, P, FP); + else + (void) des_encrypt1(block, L, IP, &L[32], + preS, E, KS, S, f, tempL, P, FP); + +/* EXPORT DELETE END */ +} + +void +des_encrypt(char *block, int edflag) +{ +/* EXPORT DELETE START */ + (void) mutex_lock(&lock); + des_encrypt_nolock(block, edflag); + (void) mutex_unlock(&lock); +/* EXPORT DELETE END */ +} + + + +#define IOBUF_SIZE 16 + +static char * +_get_iobuf(thread_key_t *key, unsigned size) +{ + char *iobuf = NULL; + + if (thr_getspecific(*key, (void **)&iobuf) != 0) { + if (_thr_keycreate(key, free) != 0) { + return (NULL); + } + } + + if (!iobuf) { + if (_thr_setspecific(*key, (void *)(iobuf = malloc(size))) + != 0) { + if (iobuf) + (void) free(iobuf); + return (NULL); + } + } + return (iobuf); +} + +char * +des_crypt(const char *pw, const char *salt) +{ +/* EXPORT DELETE START */ + int i, j; + char c, temp; + static thread_key_t key = 0; + char block[66], *iobuf = _get_iobuf(&key, IOBUF_SIZE); + + (void) mutex_lock(&lock); + for (i = 0; i < 66; i++) + block[i] = 0; + for (i = 0; (c = *pw) && (i < 64); pw++) { + for (j = 0; j < 7; j++, i++) + block[i] = (c>>(6-j)) & 01; + i++; + } + + des_setkey_nolock(block); + + for (i = 0; i < 66; i++) + block[i] = 0; + + for (i = 0; i < 2; i++) { + c = *salt++; + iobuf[i] = (char)c; + if (c > 'Z') + c -= 6; + if (c > '9') + c -= 7; + c -= '.'; + for (j = 0; j < 6; j++) { + if ((c>>j) & 01) { + temp = E[6*i+j]; + E[6*i+j] = E[6*i+j+24]; + E[6*i+j+24] = (char)temp; + } + } + } + + for (i = 0; i < 25; i++) + (void) des_encrypt_nolock(block, 0); + + for (i = 0; i < 11; i++) { + c = 0; + for (j = 0; j < 6; j++) { + c <<= 1; + c |= block[6*i+j]; + } + c += '.'; + if (c > '9') + c += 7; + if (c > 'Z') + c += 6; + iobuf[i+2] = (char)c; + } + iobuf[i+2] = 0; + if (iobuf[1] == 0) + iobuf[1] = iobuf[0]; + (void) mutex_unlock(&lock); + return (iobuf); +#if 0 +/* EXPORT DELETE END */ + return (0); +/* EXPORT DELETE START */ +#endif +/* EXPORT DELETE END */ +} |