Changeset View
Changeset View
Standalone View
Standalone View
head/sys/crypto/des/des_setkey.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <crypto/des/des_locl.h> | #include <crypto/des/des_locl.h> | ||||
#include <crypto/des/podd.h> | #include <crypto/des/podd.h> | ||||
#include <crypto/des/sk.h> | #include <crypto/des/sk.h> | ||||
int des_check_key=0; | int des_check_key=0; | ||||
void des_set_odd_parity(des_cblock *key) | void des_set_odd_parity(unsigned char *key) | ||||
{ | { | ||||
int i; | int i; | ||||
for (i=0; i<DES_KEY_SZ; i++) | for (i=0; i<DES_KEY_SZ; i++) | ||||
(*key)[i]=odd_parity[(*key)[i]]; | key[i]=odd_parity[key[i]]; | ||||
} | } | ||||
int des_check_key_parity(const des_cblock *key) | int des_check_key_parity(const unsigned char *key) | ||||
{ | { | ||||
int i; | int i; | ||||
for (i=0; i<DES_KEY_SZ; i++) | for (i=0; i<DES_KEY_SZ; i++) | ||||
{ | { | ||||
if ((*key)[i] != odd_parity[(*key)[i]]) | if (key[i] != odd_parity[key[i]]) | ||||
return(0); | return(0); | ||||
} | } | ||||
return(1); | return(1); | ||||
} | } | ||||
/* Weak and semi week keys as take from | /* Weak and semi week keys as take from | ||||
* %A D.W. Davies | * %A D.W. Davies | ||||
* %A W.L. Price | * %A W.L. Price | ||||
Show All 19 Lines | static des_cblock weak_keys[NUM_WEAK_KEY]={ | ||||
{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, | {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, | ||||
{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, | {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, | ||||
{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, | {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, | ||||
{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, | {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, | ||||
{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, | {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, | ||||
{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, | {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, | ||||
{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}}; | {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}}; | ||||
int des_is_weak_key(const des_cblock *key) | int des_is_weak_key(const unsigned char *key) | ||||
{ | { | ||||
int i; | int i; | ||||
for (i=0; i<NUM_WEAK_KEY; i++) | for (i=0; i<NUM_WEAK_KEY; i++) | ||||
/* Added == 0 to comparison, I obviously don't run | /* Added == 0 to comparison, I obviously don't run | ||||
* this section very often :-(, thanks to | * this section very often :-(, thanks to | ||||
* engineering@MorningStar.Com for the fix | * engineering@MorningStar.Com for the fix | ||||
* eay 93/06/29 | * eay 93/06/29 | ||||
* Another problem, I was comparing only the first 4 | * Another problem, I was comparing only the first 4 | ||||
* bytes, 97/03/18 */ | * bytes, 97/03/18 */ | ||||
if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1); | if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1); | ||||
return(0); | return(0); | ||||
} | } | ||||
/* NOW DEFINED IN des_local.h | /* NOW DEFINED IN des_local.h | ||||
* See ecb_encrypt.c for a pseudo description of these macros. | * See ecb_encrypt.c for a pseudo description of these macros. | ||||
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ | * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ | ||||
* (b)^=(t),\ | * (b)^=(t),\ | ||||
* (a)=((a)^((t)<<(n)))) | * (a)=((a)^((t)<<(n)))) | ||||
*/ | */ | ||||
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ | #define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ | ||||
(a)=(a)^(t)^(t>>(16-(n)))) | (a)=(a)^(t)^(t>>(16-(n)))) | ||||
int des_set_key(const des_cblock *key, des_key_schedule schedule) | int des_set_key(const unsigned char *key, des_key_schedule schedule) | ||||
{ | { | ||||
if (des_check_key) | if (des_check_key) | ||||
{ | { | ||||
return des_set_key_checked(key, schedule); | return des_set_key_checked(key, schedule); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
des_set_key_unchecked(key, schedule); | des_set_key_unchecked(key, schedule); | ||||
return 0; | return 0; | ||||
} | } | ||||
} | } | ||||
/* return 0 if key parity is odd (correct), | /* return 0 if key parity is odd (correct), | ||||
* return -1 if key parity error, | * return -1 if key parity error, | ||||
* return -2 if illegal weak key. | * return -2 if illegal weak key. | ||||
*/ | */ | ||||
int des_set_key_checked(const des_cblock *key, des_key_schedule schedule) | int des_set_key_checked(const unsigned char *key, des_key_schedule schedule) | ||||
{ | { | ||||
if (!des_check_key_parity(key)) | if (!des_check_key_parity(key)) | ||||
return(-1); | return(-1); | ||||
if (des_is_weak_key(key)) | if (des_is_weak_key(key)) | ||||
return(-2); | return(-2); | ||||
des_set_key_unchecked(key, schedule); | des_set_key_unchecked(key, schedule); | ||||
return 0; | return 0; | ||||
} | } | ||||
void des_set_key_unchecked(const des_cblock *key, des_key_schedule schedule) | void des_set_key_unchecked(const unsigned char *key, des_key_schedule schedule) | ||||
{ | { | ||||
static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; | static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; | ||||
DES_LONG c,d,t,s,t2; | DES_LONG c,d,t,s,t2; | ||||
const unsigned char *in; | const unsigned char *in; | ||||
DES_LONG *k; | DES_LONG *k; | ||||
int i; | int i; | ||||
k = &schedule->ks.deslong[0]; | k = &schedule->ks.deslong[0]; | ||||
in = &(*key)[0]; | in = key; | ||||
c2l(in,c); | c2l(in,c); | ||||
c2l(in,d); | c2l(in,d); | ||||
/* do PC1 in 47 simple operations :-) | /* do PC1 in 47 simple operations :-) | ||||
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) | * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) | ||||
* for the inspiration. :-) */ | * for the inspiration. :-) */ | ||||
PERM_OP (d,c,t,4,0x0f0f0f0fL); | PERM_OP (d,c,t,4,0x0f0f0f0fL); | ||||
Show All 30 Lines | for (i=0; i<ITERATIONS; i++) | ||||
t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; | t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; | ||||
*(k++)=ROTATE(t2,30)&0xffffffffL; | *(k++)=ROTATE(t2,30)&0xffffffffL; | ||||
t2=((s>>16L)|(t&0xffff0000L)); | t2=((s>>16L)|(t&0xffff0000L)); | ||||
*(k++)=ROTATE(t2,26)&0xffffffffL; | *(k++)=ROTATE(t2,26)&0xffffffffL; | ||||
} | } | ||||
} | } | ||||
int des_key_sched(const des_cblock *key, des_key_schedule schedule) | int des_key_sched(const unsigned char *key, des_key_schedule schedule) | ||||
{ | { | ||||
return(des_set_key(key,schedule)); | return(des_set_key(key,schedule)); | ||||
} | } | ||||
void des_fixup_key_parity(des_cblock *key) | void des_fixup_key_parity(unsigned char *key) | ||||
{ | { | ||||
des_set_odd_parity(key); | des_set_odd_parity(key); | ||||
} | } |