⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2005 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. *  * 3. Neither the name of the Institute nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * The document that got me started for real was "Efficient * Implementation of the Data Encryption Standard" by Dag Arne Osvik. * I never got to the PC1 transformation was working, instead I used * table-lookup was used for all key schedule setup. The document was * very useful since it de-mystified other implementations for me. * * The core DES function (SBOX + P transformation) is from Richard * Outerbridge public domain DES implementation. My sanity is saved * thanks to his work. Thank you Richard. */#ifdef HAVE_CONFIG_H#include <config.h>RCSID("$Id: des.c 17211 2006-04-24 14:26:19Z lha $");#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <krb5-types.h>#include <assert.h>#include "des.h"#include "ui.h"static void desx(uint32_t [2], DES_key_schedule *, int);static void IP(uint32_t [2]);static void FP(uint32_t [2]);#include "des-tables.h"#define ROTATE_LEFT28(x,one)				\    if (one) {						\	x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27);	\    } else {						\	x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26);	\    }/* * */intDES_set_odd_parity(DES_cblock *key){    int i;    for (i = 0; i < DES_CBLOCK_LEN; i++)	(*key)[i] = odd_parity[(*key)[i]];    return 0;}/* * *//* FIPS 74 */static DES_cblock weak_keys[] = {    {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */    {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},    {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},    {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},    {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */    {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},    {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},    {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},    {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},    {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},    {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},    {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},    {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},    {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},    {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},    {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};intDES_is_weak_key(DES_cblock *key){    int i;    for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {	if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)	    return 1;    }    return 0;}/* * */intDES_set_key(DES_cblock *key, DES_key_schedule *ks){    uint32_t t1, t2;    uint32_t c, d;    int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };    uint32_t *k = &ks->ks[0];    int i;    t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];    t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];    c =   (pc1_c_3[(t1 >> (5            )) & 0x7] << 3)	| (pc1_c_3[(t1 >> (5 + 8        )) & 0x7] << 2)	| (pc1_c_3[(t1 >> (5 + 8 + 8    )) & 0x7] << 1)	| (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)	| (pc1_c_4[(t2 >> (4            )) & 0xf] << 3)	| (pc1_c_4[(t2 >> (4 + 8        )) & 0xf] << 2)	| (pc1_c_4[(t2 >> (4 + 8 + 8    )) & 0xf] << 1)	| (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);        d =   (pc1_d_3[(t2 >> (1            )) & 0x7] << 3)	| (pc1_d_3[(t2 >> (1 + 8        )) & 0x7] << 2)	| (pc1_d_3[(t2 >> (1 + 8 + 8    )) & 0x7] << 1)	| (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)	| (pc1_d_4[(t1 >> (1            )) & 0xf] << 3)	| (pc1_d_4[(t1 >> (1 + 8        )) & 0xf] << 2)	| (pc1_d_4[(t1 >> (1 + 8 + 8    )) & 0xf] << 1)	| (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);    for (i = 0; i < 16; i++) {	uint32_t kc, kd;		ROTATE_LEFT28(c, shifts[i]);	ROTATE_LEFT28(d, shifts[i]);		kc = pc2_c_1[(c >> 22) & 0x3f] |	    pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |	    pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |	    pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];	kd = pc2_d_1[(d >> 22) & 0x3f] |	    pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |	    pc2_d_3[ (d >> 7 ) & 0x3f] |	    pc2_d_4[((d >> 1 ) & 0x3c) | ((d      ) & 0x3)];	/* Change to byte order used by the S boxes */	*k  =    (kc & 0x00fc0000L) << 6;	*k |=    (kc & 0x00000fc0L) << 10;	*k |=    (kd & 0x00fc0000L) >> 10;	*k++  |= (kd & 0x00000fc0L) >> 6;	*k  =    (kc & 0x0003f000L) << 12;	*k |=    (kc & 0x0000003fL) << 16;	*k |=    (kd & 0x0003f000L) >> 4;	*k++  |= (kd & 0x0000003fL);    }    return 0;}/* * */intDES_set_key_checked(DES_cblock *key, DES_key_schedule *ks){    if (DES_is_weak_key(key)) {	memset(ks, 0, sizeof(*ks));	return 1;    }    return DES_set_key(key, ks);}/* * Compatibility function for eay libdes */intDES_key_sched(DES_cblock *key, DES_key_schedule *ks){    return DES_set_key(key, ks);}/* * */static voidload(const unsigned char *b, uint32_t v[2]){    v[0] =  b[0] << 24;    v[0] |= b[1] << 16;    v[0] |= b[2] << 8;    v[0] |= b[3] << 0;    v[1] =  b[4] << 24;    v[1] |= b[5] << 16;    v[1] |= b[6] << 8;    v[1] |= b[7] << 0;}static voidstore(const uint32_t v[2], unsigned char *b){    b[0] = (v[0] >> 24) & 0xff;    b[1] = (v[0] >> 16) & 0xff;    b[2] = (v[0] >>  8) & 0xff;    b[3] = (v[0] >>  0) & 0xff;    b[4] = (v[1] >> 24) & 0xff;    b[5] = (v[1] >> 16) & 0xff;    b[6] = (v[1] >>  8) & 0xff;    b[7] = (v[1] >>  0) & 0xff;}/* * */voidDES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt){    IP(u);    desx(u, ks, forward_encrypt);    FP(u);}/* * */voidDES_ecb_encrypt(DES_cblock *input, DES_cblock *output,		DES_key_schedule *ks, int forward_encrypt){    uint32_t u[2];    load(*input, u);    DES_encrypt(u, ks, forward_encrypt);    store(u, *output);}/* * */voidDES_cbc_encrypt(const void *in, void *out, long length,		DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt){    const unsigned char *input = in;    unsigned char *output = out;    uint32_t u[2];    uint32_t uiv[2];    load(*iv, uiv);    if (forward_encrypt) {	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    DES_encrypt(u, ks, 1);	    uiv[0] = u[0]; uiv[1] = u[1];	    store(u, output);	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;	}	if (length) {	    unsigned char tmp[DES_CBLOCK_LEN];	    memcpy(tmp, input, length);	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);	    load(tmp, u);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    DES_encrypt(u, ks, 1);	    store(u, output);	}    } else {	uint32_t t[2];	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    t[0] = u[0]; t[1] = u[1];	    DES_encrypt(u, ks, 0);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    store(u, output);	    uiv[0] = t[0]; uiv[1] = t[1];	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;	}	if (length) {	    unsigned char tmp[DES_CBLOCK_LEN];	    memcpy(tmp, input, length);	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);	    load(tmp, u);	    DES_encrypt(u, ks, 0);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    store(u, output);	}    }    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;}/* * */voidDES_pcbc_encrypt(const void *in, void *out, long length,		 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt){    const unsigned char *input = in;    unsigned char *output = out;    uint32_t u[2];    uint32_t uiv[2];    load(*iv, uiv);    if (forward_encrypt) {	uint32_t t[2];	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    t[0] = u[0]; t[1] = u[1];	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    DES_encrypt(u, ks, 1);	    uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];	    store(u, output);	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;	}	if (length) {	    unsigned char tmp[DES_CBLOCK_LEN];	    memcpy(tmp, input, length);	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);	    load(tmp, u);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    DES_encrypt(u, ks, 1);	    store(u, output);	}    } else {	uint32_t t[2];	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    t[0] = u[0]; t[1] = u[1];	    DES_encrypt(u, ks, 0);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    store(u, output);	    uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;	}	if (length) {	    unsigned char tmp[DES_CBLOCK_LEN];	    memcpy(tmp, input, length);	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);	    load(tmp, u);	    DES_encrypt(u, ks, 0);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	}    }    uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;}/* * */static void_des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, 	      DES_key_schedule *ks3, int forward_encrypt){    IP(u);    if (forward_encrypt) {	desx(u, ks1, 1); /* IP + FP cancel out each other */	desx(u, ks2, 0);	desx(u, ks3, 1);    } else {	desx(u, ks3, 0);	desx(u, ks2, 1);	desx(u, ks1, 0);    }    FP(u);}/* * */voidDES_ecb3_encrypt(DES_cblock *input,		 DES_cblock *output,		 DES_key_schedule *ks1,		 DES_key_schedule *ks2,		 DES_key_schedule *ks3,		 int forward_encrypt){    uint32_t u[2];    load(*input, u);    _des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);    store(u, *output);    return;}/* * */voidDES_ede3_cbc_encrypt(const void *in, void *out,		     long length, DES_key_schedule *ks1, 		     DES_key_schedule *ks2, DES_key_schedule *ks3,		     DES_cblock *iv, int forward_encrypt){    const unsigned char *input = in;    unsigned char *output = out;    uint32_t u[2];    uint32_t uiv[2];    load(*iv, uiv);    if (forward_encrypt) {	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    _des3_encrypt(u, ks1, ks2, ks3, 1);	    uiv[0] = u[0]; uiv[1] = u[1];	    store(u, output);	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;	}	if (length) {	    unsigned char tmp[DES_CBLOCK_LEN];	    memcpy(tmp, input, length);	    memset(tmp + length, 0, DES_CBLOCK_LEN - length);	    load(tmp, u);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    _des3_encrypt(u, ks1, ks2, ks3, 1);	    store(u, output);	}    } else {	uint32_t t[2];	while (length >= DES_CBLOCK_LEN) {	    load(input, u);	    t[0] = u[0]; t[1] = u[1];	    _des3_encrypt(u, ks1, ks2, ks3, 0);	    u[0] ^= uiv[0]; u[1] ^= uiv[1];	    store(u, output);	    uiv[0] = t[0]; uiv[1] = t[1];	    length -= DES_CBLOCK_LEN;	    input += DES_CBLOCK_LEN;	    output += DES_CBLOCK_LEN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -