a
This commit is contained in:
60
libsec/Makefile
Normal file
60
libsec/Makefile
Normal file
@ -0,0 +1,60 @@
|
||||
LIB=libsec.a
|
||||
CC=gcc
|
||||
CFLAGS=-I../include -I. -c -ggdb -D_THREAD_SAFE -pthread
|
||||
O=o
|
||||
|
||||
OFILES=\
|
||||
aes.$O\
|
||||
blowfish.$O\
|
||||
decodepem.$O\
|
||||
des.$O\
|
||||
des3CBC.$O\
|
||||
des3ECB.$O\
|
||||
desCBC.$O\
|
||||
desECB.$O\
|
||||
desmodes.$O\
|
||||
dsaalloc.$O\
|
||||
dsagen.$O\
|
||||
dsaprimes.$O\
|
||||
dsaprivtopub.$O\
|
||||
dsasign.$O\
|
||||
dsaverify.$O\
|
||||
egalloc.$O\
|
||||
egdecrypt.$O\
|
||||
egencrypt.$O\
|
||||
eggen.$O\
|
||||
egprivtopub.$O\
|
||||
egsign.$O\
|
||||
egverify.$O\
|
||||
fastrand.$O\
|
||||
genprime.$O\
|
||||
genrandom.$O\
|
||||
gensafeprime.$O\
|
||||
genstrongprime.$O\
|
||||
hmac.$O\
|
||||
md4.$O\
|
||||
md5.$O\
|
||||
md5block.$O\
|
||||
md5pickle.$O\
|
||||
nfastrand.$O\
|
||||
prng.$O\
|
||||
probably_prime.$O\
|
||||
rc4.$O\
|
||||
rsaalloc.$O\
|
||||
rsadecrypt.$O\
|
||||
rsaencrypt.$O\
|
||||
rsafill.$O\
|
||||
rsagen.$O\
|
||||
rsaprivtopub.$O\
|
||||
sha1.$O\
|
||||
sha1block.$O\
|
||||
sha1pickle.$O\
|
||||
smallprimes.$O
|
||||
|
||||
$(LIB): $(OFILES)
|
||||
ar r $(LIB) $(OFILES)
|
||||
ranlib $(LIB)
|
||||
|
||||
%.$O: %.c
|
||||
$(CC) $(CFLAGS) $*.c
|
||||
|
1544
libsec/aes.c
Normal file
1544
libsec/aes.c
Normal file
File diff suppressed because it is too large
Load Diff
579
libsec/blowfish.c
Normal file
579
libsec/blowfish.c
Normal file
@ -0,0 +1,579 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// Blowfish block cipher. See:
|
||||
// Lecture Notes in Computer Science 809
|
||||
// Fast Software Encryption
|
||||
// Cambridge Security Workshop, Cambridge, England (1993)
|
||||
|
||||
static u32int sbox[1024];
|
||||
static u32int pbox[BFrounds+2];
|
||||
|
||||
static void bfencrypt(u32int *, BFstate *);
|
||||
static void bfdecrypt(u32int *, BFstate *);
|
||||
|
||||
void
|
||||
setupBFstate(BFstate *s, uchar key[], int keybytes, uchar *ivec)
|
||||
{
|
||||
int i, j;
|
||||
u32int n, buf[2];
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
memset(buf, 0, sizeof buf);
|
||||
|
||||
if (keybytes > sizeof(s->key))
|
||||
keybytes = sizeof(s->key);
|
||||
|
||||
memmove(s->key, key, keybytes);
|
||||
|
||||
if (ivec != nil)
|
||||
memmove(s->ivec, ivec, sizeof(s->ivec));
|
||||
else
|
||||
memset(s->ivec, 0, sizeof(s->ivec));
|
||||
|
||||
memmove(s->pbox, pbox, sizeof(pbox));
|
||||
memmove(s->sbox, sbox, sizeof(sbox));
|
||||
|
||||
if (keybytes > 4*(BFrounds + 2))
|
||||
keybytes = 4*(BFrounds + 2);
|
||||
|
||||
for(i=j=0; i < BFrounds+2; i++) {
|
||||
n = key[j];
|
||||
j = (j+1) % keybytes;
|
||||
|
||||
n <<= 8;
|
||||
n |= key[j];
|
||||
j = (j+1) % keybytes;
|
||||
|
||||
n <<= 8;
|
||||
n |= key[j];
|
||||
j = (j+1) % keybytes;
|
||||
|
||||
n <<= 8;
|
||||
n |= key[j];
|
||||
j = (j+1) % keybytes;
|
||||
|
||||
s->pbox[i] ^= n;
|
||||
}
|
||||
|
||||
for(i=0; i < BFrounds+2; i += 2) {
|
||||
bfencrypt(buf, s);
|
||||
s->pbox[i] = buf[0];
|
||||
s->pbox[i+1] = buf[1];
|
||||
}
|
||||
|
||||
for(i=0; i < 1024; i += 2) {
|
||||
bfencrypt(buf, s);
|
||||
s->sbox[i] = buf[0];
|
||||
s->sbox[i+1] = buf[1];
|
||||
}
|
||||
|
||||
s->setup = 0xcafebabe;
|
||||
}
|
||||
|
||||
void
|
||||
bfCBCencrypt(uchar *buf, int n, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
uchar *p;
|
||||
u32int bo[2], bi[2], b;
|
||||
|
||||
assert((n & 7) == 0);
|
||||
|
||||
bo[0] = s->ivec[0] | ((u32int) s->ivec[1]<<8) | ((u32int)s->ivec[2]<<16) | ((u32int)s->ivec[3]<<24);
|
||||
bo[1] = s->ivec[4] | ((u32int) s->ivec[5]<<8) | ((u32int)s->ivec[6]<<16) | ((u32int)s->ivec[7]<<24);
|
||||
|
||||
for(i=0; i < n; i += 8, buf += 8) {
|
||||
bi[0] = buf[0] | ((u32int) buf[1]<<8) | ((u32int)buf[2]<<16) | ((u32int)buf[3]<<24);
|
||||
bi[1] = buf[4] | ((u32int) buf[5]<<8) | ((u32int)buf[6]<<16) | ((u32int)buf[7]<<24);
|
||||
|
||||
bi[0] ^= bo[0];
|
||||
bi[1] ^= bo[1];
|
||||
|
||||
bfencrypt(bi, s);
|
||||
|
||||
bo[0] = bi[0];
|
||||
bo[1] = bi[1];
|
||||
|
||||
p = buf;
|
||||
b = bo[0];
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
|
||||
b = bo[1];
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p = b;
|
||||
}
|
||||
|
||||
s->ivec[7] = bo[1] >> 24;
|
||||
s->ivec[6] = bo[1] >> 16;
|
||||
s->ivec[5] = bo[1] >> 8;
|
||||
s->ivec[4] = bo[1];
|
||||
|
||||
s->ivec[3] = bo[0] >> 24;
|
||||
s->ivec[2] = bo[0] >> 16;
|
||||
s->ivec[1] = bo[0] >> 8;
|
||||
s->ivec[0] = bo[0];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bfCBCdecrypt(uchar *buf, int n, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
uchar *p;
|
||||
u32int b, bo[2], bi[2], xr[2];
|
||||
|
||||
assert((n & 7) == 0);
|
||||
|
||||
bo[0] = s->ivec[0] | ((u32int) s->ivec[1]<<8) | ((u32int)s->ivec[2]<<16) | ((u32int)s->ivec[3]<<24);
|
||||
bo[1] = s->ivec[4] | ((u32int) s->ivec[5]<<8) | ((u32int)s->ivec[6]<<16) | ((u32int)s->ivec[7]<<24);
|
||||
|
||||
for(i=0; i < n; i += 8, buf += 8) {
|
||||
bi[0] = buf[0] | ((u32int) buf[1]<<8) | ((u32int)buf[2]<<16) | ((u32int)buf[3]<<24);
|
||||
bi[1] = buf[4] | ((u32int) buf[5]<<8) | ((u32int)buf[6]<<16) | ((u32int)buf[7]<<24);
|
||||
|
||||
xr[0] = bi[0];
|
||||
xr[1] = bi[1];
|
||||
|
||||
bfdecrypt(bi, s);
|
||||
|
||||
bo[0] ^= bi[0];
|
||||
bo[1] ^= bi[1];
|
||||
|
||||
p = buf;
|
||||
b = bo[0];
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
|
||||
b = bo[1];
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p++ = b;
|
||||
b >>= 8;
|
||||
*p = b;
|
||||
|
||||
bo[0] = xr[0];
|
||||
bo[1] = xr[1];
|
||||
}
|
||||
|
||||
s->ivec[7] = bo[1] >> 24;
|
||||
s->ivec[6] = bo[1] >> 16;
|
||||
s->ivec[5] = bo[1] >> 8;
|
||||
s->ivec[4] = bo[1];
|
||||
|
||||
s->ivec[3] = bo[0] >> 24;
|
||||
s->ivec[2] = bo[0] >> 16;
|
||||
s->ivec[1] = bo[0] >> 8;
|
||||
s->ivec[0] = bo[0];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bfECBencrypt(uchar *buf, int n, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
u32int b[2];
|
||||
|
||||
for(i=0; i < n; i += 8, buf += 8) {
|
||||
b[0] = buf[0] | ((u32int) buf[1]<<8) | ((u32int)buf[2]<<16) | ((u32int)buf[3]<<24);
|
||||
b[1] = buf[4] | ((u32int) buf[5]<<8) | ((u32int)buf[6]<<16) | ((u32int)buf[7]<<24);
|
||||
|
||||
bfencrypt(b, s);
|
||||
|
||||
buf[7] = b[1] >> 24;
|
||||
buf[6] = b[1] >> 16;
|
||||
buf[5] = b[1] >> 8;
|
||||
buf[4] = b[1];
|
||||
|
||||
buf[3] = b[0] >> 24;
|
||||
buf[2] = b[0] >> 16;
|
||||
buf[1] = b[0] >> 8;
|
||||
buf[0] = b[0];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
bfECBdecrypt(uchar *buf, int n, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
u32int b[2];
|
||||
|
||||
for(i=0; i < n; i += 8, buf += 8) {
|
||||
b[0] = buf[0] | ((u32int) buf[1]<<8) | ((u32int)buf[2]<<16) | ((u32int)buf[3]<<24);
|
||||
b[1] = buf[4] | ((u32int) buf[5]<<8) | ((u32int)buf[6]<<16) | ((u32int)buf[7]<<24);
|
||||
|
||||
bfdecrypt(b, s);
|
||||
|
||||
buf[7] = b[1] >> 24;
|
||||
buf[6] = b[1] >> 16;
|
||||
buf[5] = b[1] >> 8;
|
||||
buf[4] = b[1];
|
||||
|
||||
buf[3] = b[0] >> 24;
|
||||
buf[2] = b[0] >> 16;
|
||||
buf[1] = b[0] >> 8;
|
||||
buf[0] = b[0];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
bfencrypt(u32int *b, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
u32int l, r;
|
||||
u32int *pb, *sb;
|
||||
|
||||
l = b[0];
|
||||
r = b[1];
|
||||
|
||||
pb = s->pbox;
|
||||
sb = s->sbox;
|
||||
|
||||
l ^= pb[0];
|
||||
|
||||
for(i=1; i<16; i += 2) {
|
||||
r ^= pb[i];
|
||||
r ^= ( (sb[ (uchar) (l>>24)] + sb[256 + ((uchar) (l>>16))]) ^
|
||||
sb[512 + ((uchar) (l>>8))]) + sb[768 +((uchar) l)];
|
||||
|
||||
l ^= pb[i+1];
|
||||
l ^= ( (sb[ (uchar) (r>>24)] + sb[256 + ((uchar) (r>>16))]) ^
|
||||
sb[512 + ((uchar) (r>>8))]) + sb[768 +((uchar) r)];
|
||||
}
|
||||
|
||||
r ^= pb[BFrounds+1];
|
||||
|
||||
/* sic */
|
||||
b[0] = r;
|
||||
b[1] = l;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
bfdecrypt(u32int *b, BFstate *s)
|
||||
{
|
||||
int i;
|
||||
u32int l, r;
|
||||
u32int *pb, *sb;
|
||||
|
||||
l = b[0];
|
||||
r = b[1];
|
||||
|
||||
pb = s->pbox;
|
||||
sb = s->sbox;
|
||||
|
||||
l ^= pb[BFrounds+1];
|
||||
|
||||
for(i=16; i > 0; i -= 2) {
|
||||
r ^= pb[i];
|
||||
r ^= ( (sb[ (uchar) (l>>24)] + sb[256 + ((uchar) (l>>16))]) ^
|
||||
sb[512 + ((uchar) (l>>8))]) + sb[768 +((uchar) l)];
|
||||
|
||||
l ^= pb[i-1];
|
||||
l ^= ( (sb[ (uchar) (r>>24)] + sb[256 + ((uchar) (r>>16))]) ^
|
||||
sb[512 + ((uchar) (r>>8))]) + sb[768 +((uchar) r)];
|
||||
}
|
||||
|
||||
r ^= pb[0];
|
||||
|
||||
/* sic */
|
||||
b[0] = r;
|
||||
b[1] = l;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static u32int pbox[BFrounds+2] = {
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
};
|
||||
|
||||
static u32int sbox[1024] = {
|
||||
0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
|
||||
0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L,
|
||||
0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
|
||||
0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
|
||||
0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL,
|
||||
0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
|
||||
0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
|
||||
0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL,
|
||||
0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
|
||||
0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
|
||||
0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL,
|
||||
0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
|
||||
0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
|
||||
0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L,
|
||||
0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
|
||||
0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
|
||||
0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L,
|
||||
0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
|
||||
0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
|
||||
0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L,
|
||||
0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
|
||||
0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
|
||||
0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L,
|
||||
0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
|
||||
0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
|
||||
0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL,
|
||||
0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
|
||||
0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
|
||||
0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL,
|
||||
0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
|
||||
0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
|
||||
0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L,
|
||||
0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
|
||||
0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
|
||||
0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L,
|
||||
0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
|
||||
0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
|
||||
0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L,
|
||||
0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
|
||||
0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
|
||||
0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L,
|
||||
0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
|
||||
0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
|
||||
0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L,
|
||||
0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
|
||||
0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
|
||||
0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L,
|
||||
0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
|
||||
0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
|
||||
0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L,
|
||||
0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
|
||||
0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
|
||||
0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L,
|
||||
0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
|
||||
0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
|
||||
0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL,
|
||||
0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
|
||||
0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
|
||||
0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L,
|
||||
0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
|
||||
0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
|
||||
0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L,
|
||||
0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
|
||||
0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
|
||||
0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
|
||||
0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L,
|
||||
0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
|
||||
0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
|
||||
0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L,
|
||||
0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
|
||||
0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
|
||||
0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L,
|
||||
0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
|
||||
0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
|
||||
0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL,
|
||||
0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
|
||||
0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
|
||||
0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L,
|
||||
0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
|
||||
0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
|
||||
0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL,
|
||||
0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
|
||||
0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
|
||||
0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L,
|
||||
0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
|
||||
0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
|
||||
0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L,
|
||||
0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
|
||||
0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
|
||||
0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L,
|
||||
0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
|
||||
0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
|
||||
0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL,
|
||||
0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
|
||||
0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
|
||||
0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L,
|
||||
0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
|
||||
0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
|
||||
0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L,
|
||||
0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
|
||||
0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
|
||||
0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL,
|
||||
0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
|
||||
0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
|
||||
0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L,
|
||||
0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
|
||||
0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
|
||||
0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L,
|
||||
0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
|
||||
0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
|
||||
0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L,
|
||||
0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
|
||||
0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
|
||||
0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L,
|
||||
0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
|
||||
0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
|
||||
0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L,
|
||||
0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
|
||||
0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
|
||||
0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L,
|
||||
0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
|
||||
0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
|
||||
0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L,
|
||||
0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
|
||||
0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
|
||||
0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L,
|
||||
0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
|
||||
0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L,
|
||||
0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
|
||||
0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L,
|
||||
0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
|
||||
0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
|
||||
0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L,
|
||||
0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
|
||||
0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
|
||||
0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL,
|
||||
0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
|
||||
0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
|
||||
0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L,
|
||||
0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
|
||||
0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
|
||||
0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL,
|
||||
0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
|
||||
0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
|
||||
0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L,
|
||||
0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
|
||||
0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
|
||||
0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL,
|
||||
0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
|
||||
0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
|
||||
0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL,
|
||||
0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
|
||||
0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
|
||||
0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L,
|
||||
0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
|
||||
0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
|
||||
0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L,
|
||||
0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
|
||||
0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
|
||||
0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL,
|
||||
0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
|
||||
0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
|
||||
0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL,
|
||||
0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
|
||||
0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
|
||||
0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L,
|
||||
0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
|
||||
0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
|
||||
0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL,
|
||||
0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
|
||||
0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
|
||||
0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L,
|
||||
0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
|
||||
0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
|
||||
0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L,
|
||||
0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
|
||||
0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
|
||||
0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L,
|
||||
0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
|
||||
0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
|
||||
0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L,
|
||||
0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
|
||||
0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
|
||||
0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L,
|
||||
0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
|
||||
0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
|
||||
0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L,
|
||||
0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
|
||||
0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
|
||||
0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL,
|
||||
0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
|
||||
0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L,
|
||||
0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
|
||||
0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL,
|
||||
0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
|
||||
0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
|
||||
0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L,
|
||||
0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
|
||||
0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
|
||||
0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L,
|
||||
0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
|
||||
0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
|
||||
0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L,
|
||||
0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
|
||||
0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
|
||||
0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L,
|
||||
0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
|
||||
0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
|
||||
0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL,
|
||||
0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
|
||||
0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
|
||||
0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL,
|
||||
0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
|
||||
0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
|
||||
0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL,
|
||||
0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
|
||||
0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
|
||||
0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L,
|
||||
0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
|
||||
0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
|
||||
0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL,
|
||||
0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
|
||||
0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
|
||||
0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L,
|
||||
0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
|
||||
0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
|
||||
0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L,
|
||||
0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
|
||||
0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
|
||||
0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL,
|
||||
0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
|
||||
0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
|
||||
0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L,
|
||||
0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
|
||||
0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
|
||||
0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L,
|
||||
0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
|
||||
0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
|
||||
0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L,
|
||||
0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
|
||||
0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
|
||||
0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL,
|
||||
0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
|
||||
0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
|
||||
0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L,
|
||||
0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
|
||||
0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
|
||||
0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL,
|
||||
0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
|
||||
0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
|
||||
0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L,
|
||||
0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
|
||||
0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
|
||||
0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L,
|
||||
0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
|
||||
0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L,
|
||||
};
|
||||
|
||||
|
59
libsec/decodepem.c
Normal file
59
libsec/decodepem.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
#define STRLEN(s) (sizeof(s)-1)
|
||||
|
||||
uchar*
|
||||
decodepem(char *s, char *type, int *len)
|
||||
{
|
||||
uchar *d;
|
||||
char *t, *e, *tt;
|
||||
int n;
|
||||
|
||||
/*
|
||||
* find the correct section of the file, stripping garbage at the beginning and end.
|
||||
* the data is delimited by -----BEGIN <type>-----\n and -----END <type>-----\n
|
||||
*/
|
||||
n = strlen(type);
|
||||
e = strchr(s, '\0');
|
||||
for(t = s; t != nil && t < e; ){
|
||||
tt = t;
|
||||
t = strchr(tt, '\n');
|
||||
if(t != nil)
|
||||
t++;
|
||||
if(strncmp(tt, "-----BEGIN ", STRLEN("-----BEGIN ")) == 0
|
||||
&& strncmp(&tt[STRLEN("-----BEGIN ")], type, n) == 0
|
||||
&& strncmp(&tt[STRLEN("-----BEGIN ")+n], "-----\n", STRLEN("-----\n")) == 0)
|
||||
break;
|
||||
}
|
||||
for(tt = t; tt != nil && tt < e; tt++){
|
||||
if(strncmp(tt, "-----END ", STRLEN("-----END ")) == 0
|
||||
&& strncmp(&tt[STRLEN("-----END ")], type, n) == 0
|
||||
&& strncmp(&tt[STRLEN("-----END ")+n], "-----\n", STRLEN("-----\n")) == 0)
|
||||
break;
|
||||
tt = strchr(tt, '\n');
|
||||
if(tt == nil)
|
||||
break;
|
||||
}
|
||||
if(tt == nil || tt == e){
|
||||
werrstr("incorrect .pem file format: bad header or trailer");
|
||||
return nil;
|
||||
}
|
||||
|
||||
n = ((tt - t) * 6 + 7) / 8;
|
||||
d = malloc(n);
|
||||
if(d == nil){
|
||||
werrstr("out of memory");
|
||||
return nil;
|
||||
}
|
||||
n = dec64(d, n, t, tt - t);
|
||||
if(n < 0){
|
||||
free(d);
|
||||
werrstr("incorrect .pem file format: bad base64 encoded data");
|
||||
return nil;
|
||||
}
|
||||
*len = n;
|
||||
return d;
|
||||
}
|
480
libsec/des.c
Normal file
480
libsec/des.c
Normal file
@ -0,0 +1,480 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* integrated sbox & p perm
|
||||
*/
|
||||
static u32int spbox[] = {
|
||||
|
||||
0x00808200,0x00000000,0x00008000,0x00808202,0x00808002,0x00008202,0x00000002,0x00008000,
|
||||
0x00000200,0x00808200,0x00808202,0x00000200,0x00800202,0x00808002,0x00800000,0x00000002,
|
||||
0x00000202,0x00800200,0x00800200,0x00008200,0x00008200,0x00808000,0x00808000,0x00800202,
|
||||
0x00008002,0x00800002,0x00800002,0x00008002,0x00000000,0x00000202,0x00008202,0x00800000,
|
||||
0x00008000,0x00808202,0x00000002,0x00808000,0x00808200,0x00800000,0x00800000,0x00000200,
|
||||
0x00808002,0x00008000,0x00008200,0x00800002,0x00000200,0x00000002,0x00800202,0x00008202,
|
||||
0x00808202,0x00008002,0x00808000,0x00800202,0x00800002,0x00000202,0x00008202,0x00808200,
|
||||
0x00000202,0x00800200,0x00800200,0x00000000,0x00008002,0x00008200,0x00000000,0x00808002,
|
||||
|
||||
0x40084010,0x40004000,0x00004000,0x00084010,0x00080000,0x00000010,0x40080010,0x40004010,
|
||||
0x40000010,0x40084010,0x40084000,0x40000000,0x40004000,0x00080000,0x00000010,0x40080010,
|
||||
0x00084000,0x00080010,0x40004010,0x00000000,0x40000000,0x00004000,0x00084010,0x40080000,
|
||||
0x00080010,0x40000010,0x00000000,0x00084000,0x00004010,0x40084000,0x40080000,0x00004010,
|
||||
0x00000000,0x00084010,0x40080010,0x00080000,0x40004010,0x40080000,0x40084000,0x00004000,
|
||||
0x40080000,0x40004000,0x00000010,0x40084010,0x00084010,0x00000010,0x00004000,0x40000000,
|
||||
0x00004010,0x40084000,0x00080000,0x40000010,0x00080010,0x40004010,0x40000010,0x00080010,
|
||||
0x00084000,0x00000000,0x40004000,0x00004010,0x40000000,0x40080010,0x40084010,0x00084000,
|
||||
|
||||
0x00000104,0x04010100,0x00000000,0x04010004,0x04000100,0x00000000,0x00010104,0x04000100,
|
||||
0x00010004,0x04000004,0x04000004,0x00010000,0x04010104,0x00010004,0x04010000,0x00000104,
|
||||
0x04000000,0x00000004,0x04010100,0x00000100,0x00010100,0x04010000,0x04010004,0x00010104,
|
||||
0x04000104,0x00010100,0x00010000,0x04000104,0x00000004,0x04010104,0x00000100,0x04000000,
|
||||
0x04010100,0x04000000,0x00010004,0x00000104,0x00010000,0x04010100,0x04000100,0x00000000,
|
||||
0x00000100,0x00010004,0x04010104,0x04000100,0x04000004,0x00000100,0x00000000,0x04010004,
|
||||
0x04000104,0x00010000,0x04000000,0x04010104,0x00000004,0x00010104,0x00010100,0x04000004,
|
||||
0x04010000,0x04000104,0x00000104,0x04010000,0x00010104,0x00000004,0x04010004,0x00010100,
|
||||
|
||||
0x80401000,0x80001040,0x80001040,0x00000040,0x00401040,0x80400040,0x80400000,0x80001000,
|
||||
0x00000000,0x00401000,0x00401000,0x80401040,0x80000040,0x00000000,0x00400040,0x80400000,
|
||||
0x80000000,0x00001000,0x00400000,0x80401000,0x00000040,0x00400000,0x80001000,0x00001040,
|
||||
0x80400040,0x80000000,0x00001040,0x00400040,0x00001000,0x00401040,0x80401040,0x80000040,
|
||||
0x00400040,0x80400000,0x00401000,0x80401040,0x80000040,0x00000000,0x00000000,0x00401000,
|
||||
0x00001040,0x00400040,0x80400040,0x80000000,0x80401000,0x80001040,0x80001040,0x00000040,
|
||||
0x80401040,0x80000040,0x80000000,0x00001000,0x80400000,0x80001000,0x00401040,0x80400040,
|
||||
0x80001000,0x00001040,0x00400000,0x80401000,0x00000040,0x00400000,0x00001000,0x00401040,
|
||||
|
||||
0x00000080,0x01040080,0x01040000,0x21000080,0x00040000,0x00000080,0x20000000,0x01040000,
|
||||
0x20040080,0x00040000,0x01000080,0x20040080,0x21000080,0x21040000,0x00040080,0x20000000,
|
||||
0x01000000,0x20040000,0x20040000,0x00000000,0x20000080,0x21040080,0x21040080,0x01000080,
|
||||
0x21040000,0x20000080,0x00000000,0x21000000,0x01040080,0x01000000,0x21000000,0x00040080,
|
||||
0x00040000,0x21000080,0x00000080,0x01000000,0x20000000,0x01040000,0x21000080,0x20040080,
|
||||
0x01000080,0x20000000,0x21040000,0x01040080,0x20040080,0x00000080,0x01000000,0x21040000,
|
||||
0x21040080,0x00040080,0x21000000,0x21040080,0x01040000,0x00000000,0x20040000,0x21000000,
|
||||
0x00040080,0x01000080,0x20000080,0x00040000,0x00000000,0x20040000,0x01040080,0x20000080,
|
||||
|
||||
0x10000008,0x10200000,0x00002000,0x10202008,0x10200000,0x00000008,0x10202008,0x00200000,
|
||||
0x10002000,0x00202008,0x00200000,0x10000008,0x00200008,0x10002000,0x10000000,0x00002008,
|
||||
0x00000000,0x00200008,0x10002008,0x00002000,0x00202000,0x10002008,0x00000008,0x10200008,
|
||||
0x10200008,0x00000000,0x00202008,0x10202000,0x00002008,0x00202000,0x10202000,0x10000000,
|
||||
0x10002000,0x00000008,0x10200008,0x00202000,0x10202008,0x00200000,0x00002008,0x10000008,
|
||||
0x00200000,0x10002000,0x10000000,0x00002008,0x10000008,0x10202008,0x00202000,0x10200000,
|
||||
0x00202008,0x10202000,0x00000000,0x10200008,0x00000008,0x00002000,0x10200000,0x00202008,
|
||||
0x00002000,0x00200008,0x10002008,0x00000000,0x10202000,0x10000000,0x00200008,0x10002008,
|
||||
|
||||
0x00100000,0x02100001,0x02000401,0x00000000,0x00000400,0x02000401,0x00100401,0x02100400,
|
||||
0x02100401,0x00100000,0x00000000,0x02000001,0x00000001,0x02000000,0x02100001,0x00000401,
|
||||
0x02000400,0x00100401,0x00100001,0x02000400,0x02000001,0x02100000,0x02100400,0x00100001,
|
||||
0x02100000,0x00000400,0x00000401,0x02100401,0x00100400,0x00000001,0x02000000,0x00100400,
|
||||
0x02000000,0x00100400,0x00100000,0x02000401,0x02000401,0x02100001,0x02100001,0x00000001,
|
||||
0x00100001,0x02000000,0x02000400,0x00100000,0x02100400,0x00000401,0x00100401,0x02100400,
|
||||
0x00000401,0x02000001,0x02100401,0x02100000,0x00100400,0x00000000,0x00000001,0x02100401,
|
||||
0x00000000,0x00100401,0x02100000,0x00000400,0x02000001,0x02000400,0x00000400,0x00100001,
|
||||
|
||||
0x08000820,0x00000800,0x00020000,0x08020820,0x08000000,0x08000820,0x00000020,0x08000000,
|
||||
0x00020020,0x08020000,0x08020820,0x00020800,0x08020800,0x00020820,0x00000800,0x00000020,
|
||||
0x08020000,0x08000020,0x08000800,0x00000820,0x00020800,0x00020020,0x08020020,0x08020800,
|
||||
0x00000820,0x00000000,0x00000000,0x08020020,0x08000020,0x08000800,0x00020820,0x00020000,
|
||||
0x00020820,0x00020000,0x08020800,0x00000800,0x00000020,0x08020020,0x00000800,0x00020820,
|
||||
0x08000800,0x00000020,0x08000020,0x08020000,0x08020020,0x08000000,0x00020000,0x08000820,
|
||||
0x00000000,0x08020820,0x00020020,0x08000020,0x08020000,0x08000800,0x08000820,0x00000000,
|
||||
0x08020820,0x00020800,0x00020800,0x00000820,0x00000820,0x00020020,0x08000000,0x08020800,
|
||||
};
|
||||
|
||||
/*
|
||||
* for manual index calculation
|
||||
* #define fetch(box, i, sh) (*((u32int*)((uchar*)spbox + (box << 8) + ((i >> (sh)) & 0xfc))))
|
||||
*/
|
||||
#define fetch(box, i, sh) ((spbox+(box << 6))[((i >> (sh + 2)) & 0x3f)])
|
||||
|
||||
/*
|
||||
* DES electronic codebook encryption of one block
|
||||
*/
|
||||
void
|
||||
block_cipher(ulong key[32], uchar text[8], int decrypting)
|
||||
{
|
||||
u32int right, left, v0, v1;
|
||||
int i, keystep;
|
||||
|
||||
/*
|
||||
* initial permutation
|
||||
*/
|
||||
v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
|
||||
left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
|
||||
right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
|
||||
left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
|
||||
left = ((left << 6) & 0x33003300)
|
||||
| (left & 0xcc33cc33)
|
||||
| ((left >> 6) & 0x00cc00cc);
|
||||
left = ((left << 12) & 0x0f0f0000)
|
||||
| (left & 0xf0f00f0f)
|
||||
| ((left >> 12) & 0x0000f0f0);
|
||||
right = ((right << 6) & 0x33003300)
|
||||
| (right & 0xcc33cc33)
|
||||
| ((right >> 6) & 0x00cc00cc);
|
||||
right = ((right << 12) & 0x0f0f0000)
|
||||
| (right & 0xf0f00f0f)
|
||||
| ((right >> 12) & 0x0000f0f0);
|
||||
|
||||
if (decrypting) {
|
||||
keystep = -2;
|
||||
key = key + 32 - 2;
|
||||
} else
|
||||
keystep = 2;
|
||||
for (i = 0; i < 8; i++) {
|
||||
v0 = key[0];
|
||||
v0 ^= (right >> 1) | (right << 31);
|
||||
left ^= fetch(0, v0, 24)
|
||||
^ fetch(2, v0, 16)
|
||||
^ fetch(4, v0, 8)
|
||||
^ fetch(6, v0, 0);
|
||||
v1 = key[1];
|
||||
v1 ^= (right << 3) | (right >> 29);
|
||||
left ^= fetch(1, v1, 24)
|
||||
^ fetch(3, v1, 16)
|
||||
^ fetch(5, v1, 8)
|
||||
^ fetch(7, v1, 0);
|
||||
key += keystep;
|
||||
|
||||
v0 = key[0];
|
||||
v0 ^= (left >> 1) | (left << 31);
|
||||
right ^= fetch(0, v0, 24)
|
||||
^ fetch(2, v0, 16)
|
||||
^ fetch(4, v0, 8)
|
||||
^ fetch(6, v0, 0);
|
||||
v1 = key[1];
|
||||
v1 ^= (left << 3) | (left >> 29);
|
||||
right ^= fetch(1, v1, 24)
|
||||
^ fetch(3, v1, 16)
|
||||
^ fetch(5, v1, 8)
|
||||
^ fetch(7, v1, 0);
|
||||
key += keystep;
|
||||
}
|
||||
|
||||
/*
|
||||
* final permutation, inverse initial permutation
|
||||
*/
|
||||
v0 = ((left << 1) & 0xaaaaaaaa) | (right & 0x55555555);
|
||||
v1 = (left & 0xaaaaaaaa) | ((right >> 1) & 0x55555555);
|
||||
v1 = ((v1 << 6) & 0x33003300)
|
||||
| (v1 & 0xcc33cc33)
|
||||
| ((v1 >> 6) & 0x00cc00cc);
|
||||
v1 = ((v1 << 12) & 0x0f0f0000)
|
||||
| (v1 & 0xf0f00f0f)
|
||||
| ((v1 >> 12) & 0x0000f0f0);
|
||||
v0 = ((v0 << 6) & 0x33003300)
|
||||
| (v0 & 0xcc33cc33)
|
||||
| ((v0 >> 6) & 0x00cc00cc);
|
||||
v0 = ((v0 << 12) & 0x0f0f0000)
|
||||
| (v0 & 0xf0f00f0f)
|
||||
| ((v0 >> 12) & 0x0000f0f0);
|
||||
text[0] = v0;
|
||||
text[2] = v0 >> 8;
|
||||
text[4] = v0 >> 16;
|
||||
text[6] = v0 >> 24;
|
||||
text[1] = v1;
|
||||
text[3] = v1 >> 8;
|
||||
text[5] = v1 >> 16;
|
||||
text[7] = v1 >> 24;
|
||||
}
|
||||
|
||||
/*
|
||||
* triple DES electronic codebook encryption of one block
|
||||
*/
|
||||
void
|
||||
triple_block_cipher(ulong expanded_key[3][32], uchar text[8], int ende)
|
||||
{
|
||||
ulong *key;
|
||||
u32int right, left, v0, v1;
|
||||
int i, j, keystep;
|
||||
|
||||
/*
|
||||
* initial permutation
|
||||
*/
|
||||
v0 = text[0] | ((u32int)text[2]<<8) | ((u32int)text[4]<<16) | ((u32int)text[6]<<24);
|
||||
left = text[1] | ((u32int)text[3]<<8) | ((u32int)text[5]<<16) | ((u32int)text[7]<<24);
|
||||
right = (left & 0xaaaaaaaa) | ((v0 >> 1) & 0x55555555);
|
||||
left = ((left << 1) & 0xaaaaaaaa) | (v0 & 0x55555555);
|
||||
left = ((left << 6) & 0x33003300)
|
||||
| (left & 0xcc33cc33)
|
||||
| ((left >> 6) & 0x00cc00cc);
|
||||
left = ((left << 12) & 0x0f0f0000)
|
||||
| (left & 0xf0f00f0f)
|
||||
| ((left >> 12) & 0x0000f0f0);
|
||||
right = ((right << 6) & 0x33003300)
|
||||
| (right & 0xcc33cc33)
|
||||
| ((right >> 6) & 0x00cc00cc);
|
||||
right = ((right << 12) & 0x0f0f0000)
|
||||
| (right & 0xf0f00f0f)
|
||||
| ((right >> 12) & 0x0000f0f0);
|
||||
|
||||
for(j = 0; j < 3; j++){
|
||||
if((ende & 1) == DES3D) {
|
||||
key = &expanded_key[2-j][32-2];
|
||||
keystep = -2;
|
||||
} else {
|
||||
key = &expanded_key[j][0];
|
||||
keystep = 2;
|
||||
}
|
||||
ende >>= 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
v0 = key[0];
|
||||
v0 ^= (right >> 1) | (right << 31);
|
||||
left ^= fetch(0, v0, 24)
|
||||
^ fetch(2, v0, 16)
|
||||
^ fetch(4, v0, 8)
|
||||
^ fetch(6, v0, 0);
|
||||
v1 = key[1];
|
||||
v1 ^= (right << 3) | (right >> 29);
|
||||
left ^= fetch(1, v1, 24)
|
||||
^ fetch(3, v1, 16)
|
||||
^ fetch(5, v1, 8)
|
||||
^ fetch(7, v1, 0);
|
||||
key += keystep;
|
||||
|
||||
v0 = key[0];
|
||||
v0 ^= (left >> 1) | (left << 31);
|
||||
right ^= fetch(0, v0, 24)
|
||||
^ fetch(2, v0, 16)
|
||||
^ fetch(4, v0, 8)
|
||||
^ fetch(6, v0, 0);
|
||||
v1 = key[1];
|
||||
v1 ^= (left << 3) | (left >> 29);
|
||||
right ^= fetch(1, v1, 24)
|
||||
^ fetch(3, v1, 16)
|
||||
^ fetch(5, v1, 8)
|
||||
^ fetch(7, v1, 0);
|
||||
key += keystep;
|
||||
}
|
||||
|
||||
v0 = left;
|
||||
left = right;
|
||||
right = v0;
|
||||
}
|
||||
|
||||
/*
|
||||
* final permutation, inverse initial permutation
|
||||
* left and right are swapped here
|
||||
*/
|
||||
v0 = ((right << 1) & 0xaaaaaaaa) | (left & 0x55555555);
|
||||
v1 = (right & 0xaaaaaaaa) | ((left >> 1) & 0x55555555);
|
||||
v1 = ((v1 << 6) & 0x33003300)
|
||||
| (v1 & 0xcc33cc33)
|
||||
| ((v1 >> 6) & 0x00cc00cc);
|
||||
v1 = ((v1 << 12) & 0x0f0f0000)
|
||||
| (v1 & 0xf0f00f0f)
|
||||
| ((v1 >> 12) & 0x0000f0f0);
|
||||
v0 = ((v0 << 6) & 0x33003300)
|
||||
| (v0 & 0xcc33cc33)
|
||||
| ((v0 >> 6) & 0x00cc00cc);
|
||||
v0 = ((v0 << 12) & 0x0f0f0000)
|
||||
| (v0 & 0xf0f00f0f)
|
||||
| ((v0 >> 12) & 0x0000f0f0);
|
||||
text[0] = v0;
|
||||
text[2] = v0 >> 8;
|
||||
text[4] = v0 >> 16;
|
||||
text[6] = v0 >> 24;
|
||||
text[1] = v1;
|
||||
text[3] = v1 >> 8;
|
||||
text[5] = v1 >> 16;
|
||||
text[7] = v1 >> 24;
|
||||
}
|
||||
|
||||
/*
|
||||
* key compression permutation, 4 bits at a time
|
||||
*/
|
||||
static u32int comptab[] = {
|
||||
|
||||
0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
|
||||
0x000000,0x010000,0x000008,0x010008,0x000080,0x010080,0x000088,0x010088,
|
||||
|
||||
0x000000,0x100000,0x000800,0x100800,0x000000,0x100000,0x000800,0x100800,
|
||||
0x002000,0x102000,0x002800,0x102800,0x002000,0x102000,0x002800,0x102800,
|
||||
|
||||
0x000000,0x000004,0x000400,0x000404,0x000000,0x000004,0x000400,0x000404,
|
||||
0x400000,0x400004,0x400400,0x400404,0x400000,0x400004,0x400400,0x400404,
|
||||
|
||||
0x000000,0x000020,0x008000,0x008020,0x800000,0x800020,0x808000,0x808020,
|
||||
0x000002,0x000022,0x008002,0x008022,0x800002,0x800022,0x808002,0x808022,
|
||||
|
||||
0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
|
||||
0x000000,0x000200,0x200000,0x200200,0x001000,0x001200,0x201000,0x201200,
|
||||
|
||||
0x000000,0x000040,0x000010,0x000050,0x004000,0x004040,0x004010,0x004050,
|
||||
0x040000,0x040040,0x040010,0x040050,0x044000,0x044040,0x044010,0x044050,
|
||||
|
||||
0x000000,0x000100,0x020000,0x020100,0x000001,0x000101,0x020001,0x020101,
|
||||
0x080000,0x080100,0x0a0000,0x0a0100,0x080001,0x080101,0x0a0001,0x0a0101,
|
||||
|
||||
0x000000,0x000100,0x040000,0x040100,0x000000,0x000100,0x040000,0x040100,
|
||||
0x000040,0x000140,0x040040,0x040140,0x000040,0x000140,0x040040,0x040140,
|
||||
|
||||
0x000000,0x400000,0x008000,0x408000,0x000008,0x400008,0x008008,0x408008,
|
||||
0x000400,0x400400,0x008400,0x408400,0x000408,0x400408,0x008408,0x408408,
|
||||
|
||||
0x000000,0x001000,0x080000,0x081000,0x000020,0x001020,0x080020,0x081020,
|
||||
0x004000,0x005000,0x084000,0x085000,0x004020,0x005020,0x084020,0x085020,
|
||||
|
||||
0x000000,0x000800,0x000000,0x000800,0x000010,0x000810,0x000010,0x000810,
|
||||
0x800000,0x800800,0x800000,0x800800,0x800010,0x800810,0x800010,0x800810,
|
||||
|
||||
0x000000,0x010000,0x000200,0x010200,0x000000,0x010000,0x000200,0x010200,
|
||||
0x100000,0x110000,0x100200,0x110200,0x100000,0x110000,0x100200,0x110200,
|
||||
|
||||
0x000000,0x000004,0x000000,0x000004,0x000080,0x000084,0x000080,0x000084,
|
||||
0x002000,0x002004,0x002000,0x002004,0x002080,0x002084,0x002080,0x002084,
|
||||
|
||||
0x000000,0x000001,0x200000,0x200001,0x020000,0x020001,0x220000,0x220001,
|
||||
0x000002,0x000003,0x200002,0x200003,0x020002,0x020003,0x220002,0x220003,
|
||||
};
|
||||
|
||||
static int keysh[] =
|
||||
{
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
|
||||
};
|
||||
|
||||
static void
|
||||
keycompperm(u32int left, u32int right, ulong *ek)
|
||||
{
|
||||
u32int v0, v1;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 16; i++){
|
||||
left = (left << keysh[i]) | (left >> (28 - keysh[i]));
|
||||
left &= 0xfffffff0;
|
||||
right = (right << keysh[i]) | (right >> (28 - keysh[i]));
|
||||
right &= 0xfffffff0;
|
||||
v0 = comptab[6 * (1 << 4) + ((left >> (32-4)) & 0xf)]
|
||||
| comptab[5 * (1 << 4) + ((left >> (32-8)) & 0xf)]
|
||||
| comptab[4 * (1 << 4) + ((left >> (32-12)) & 0xf)]
|
||||
| comptab[3 * (1 << 4) + ((left >> (32-16)) & 0xf)]
|
||||
| comptab[2 * (1 << 4) + ((left >> (32-20)) & 0xf)]
|
||||
| comptab[1 * (1 << 4) + ((left >> (32-24)) & 0xf)]
|
||||
| comptab[0 * (1 << 4) + ((left >> (32-28)) & 0xf)];
|
||||
v1 = comptab[13 * (1 << 4) + ((right >> (32-4)) & 0xf)]
|
||||
| comptab[12 * (1 << 4) + ((right >> (32-8)) & 0xf)]
|
||||
| comptab[11 * (1 << 4) + ((right >> (32-12)) & 0xf)]
|
||||
| comptab[10 * (1 << 4) + ((right >> (32-16)) & 0xf)]
|
||||
| comptab[9 * (1 << 4) + ((right >> (32-20)) & 0xf)]
|
||||
| comptab[8 * (1 << 4) + ((right >> (32-24)) & 0xf)]
|
||||
| comptab[7 * (1 << 4) + ((right >> (32-28)) & 0xf)];
|
||||
ek[0] = (((v0 >> (24-6)) & 0x3f) << 26)
|
||||
| (((v0 >> (24-18)) & 0x3f) << 18)
|
||||
| (((v1 >> (24-6)) & 0x3f) << 10)
|
||||
| (((v1 >> (24-18)) & 0x3f) << 2);
|
||||
ek[1] = (((v0 >> (24-12)) & 0x3f) << 26)
|
||||
| (((v0 >> (24-24)) & 0x3f) << 18)
|
||||
| (((v1 >> (24-12)) & 0x3f) << 10)
|
||||
| (((v1 >> (24-24)) & 0x3f) << 2);
|
||||
ek += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
des_key_setup(uchar key[8], ulong *ek)
|
||||
{
|
||||
u32int left, right, v0, v1;
|
||||
|
||||
v0 = key[0] | ((u32int)key[2] << 8) | ((u32int)key[4] << 16) | ((u32int)key[6] << 24);
|
||||
v1 = key[1] | ((u32int)key[3] << 8) | ((u32int)key[5] << 16) | ((u32int)key[7] << 24);
|
||||
left = ((v0 >> 1) & 0x40404040)
|
||||
| ((v0 >> 2) & 0x10101010)
|
||||
| ((v0 >> 3) & 0x04040404)
|
||||
| ((v0 >> 4) & 0x01010101)
|
||||
| ((v1 >> 0) & 0x80808080)
|
||||
| ((v1 >> 1) & 0x20202020)
|
||||
| ((v1 >> 2) & 0x08080808)
|
||||
| ((v1 >> 3) & 0x02020202);
|
||||
right = ((v0 >> 1) & 0x04040404)
|
||||
| ((v0 << 2) & 0x10101010)
|
||||
| ((v0 << 5) & 0x40404040)
|
||||
| ((v1 << 0) & 0x08080808)
|
||||
| ((v1 << 3) & 0x20202020)
|
||||
| ((v1 << 6) & 0x80808080);
|
||||
left = ((left << 6) & 0x33003300)
|
||||
| (left & 0xcc33cc33)
|
||||
| ((left >> 6) & 0x00cc00cc);
|
||||
v0 = ((left << 12) & 0x0f0f0000)
|
||||
| (left & 0xf0f00f0f)
|
||||
| ((left >> 12) & 0x0000f0f0);
|
||||
right = ((right << 6) & 0x33003300)
|
||||
| (right & 0xcc33cc33)
|
||||
| ((right >> 6) & 0x00cc00cc);
|
||||
v1 = ((right << 12) & 0x0f0f0000)
|
||||
| (right & 0xf0f00f0f)
|
||||
| ((right >> 12) & 0x0000f0f0);
|
||||
left = v0 & 0xfffffff0;
|
||||
right = (v1 & 0xffffff00) | ((v0 << 4) & 0xf0);
|
||||
|
||||
keycompperm(left, right, ek);
|
||||
}
|
||||
|
||||
static uchar parity[128] =
|
||||
{
|
||||
0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
|
||||
0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
|
||||
0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
|
||||
0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
|
||||
0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
|
||||
0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
|
||||
0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
|
||||
0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
|
||||
0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
|
||||
0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
|
||||
0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
|
||||
0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
|
||||
0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
|
||||
0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
|
||||
0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
|
||||
0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe,
|
||||
};
|
||||
|
||||
/*
|
||||
* convert a 7 byte key to an 8 byte one
|
||||
*/
|
||||
void
|
||||
des56to64(uchar *k56, uchar *k64)
|
||||
{
|
||||
u32int hi, lo;
|
||||
|
||||
hi = ((u32int)k56[0]<<24)|((u32int)k56[1]<<16)|((u32int)k56[2]<<8)|k56[3];
|
||||
lo = ((u32int)k56[4]<<24)|((u32int)k56[5]<<16)|((u32int)k56[6]<<8);
|
||||
|
||||
k64[0] = parity[(hi>>25)&0x7f];
|
||||
k64[1] = parity[(hi>>18)&0x7f];
|
||||
k64[2] = parity[(hi>>11)&0x7f];
|
||||
k64[3] = parity[(hi>>4)&0x7f];
|
||||
k64[4] = parity[((hi<<3)|(lo>>29))&0x7f];
|
||||
k64[5] = parity[(lo>>22)&0x7f];
|
||||
k64[6] = parity[(lo>>15)&0x7f];
|
||||
k64[7] = parity[(lo>>8)&0x7f];
|
||||
}
|
||||
|
||||
/*
|
||||
* convert an 8 byte key to a 7 byte one
|
||||
*/
|
||||
void
|
||||
des64to56(uchar *k64, uchar *k56)
|
||||
{
|
||||
u32int hi, lo;
|
||||
|
||||
hi = (((u32int)k64[0]&0xfe)<<24)|(((u32int)k64[1]&0xfe)<<17)|(((u32int)k64[2]&0xfe)<<10)
|
||||
|((k64[3]&0xfe)<<3)|(k64[4]>>4);
|
||||
lo = (((u32int)k64[4]&0xfe)<<28)|(((u32int)k64[5]&0xfe)<<21)|(((u32int)k64[6]&0xfe)<<14)
|
||||
|(((u32int)k64[7]&0xfe)<<7);
|
||||
|
||||
k56[0] = hi>>24;
|
||||
k56[1] = hi>>16;
|
||||
k56[2] = hi>>8;
|
||||
k56[3] = hi>>0;
|
||||
k56[4] = lo>>24;
|
||||
k56[5] = lo>>16;
|
||||
k56[6] = lo>>8;
|
||||
}
|
||||
|
||||
void
|
||||
key_setup(uchar key[7], ulong *ek)
|
||||
{
|
||||
uchar k64[8];
|
||||
|
||||
des56to64(key, k64);
|
||||
des_key_setup(k64, ek);
|
||||
}
|
59
libsec/des3CBC.c
Normal file
59
libsec/des3CBC.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// Because of the way that non multiple of 8
|
||||
// buffers are handled, the decryptor must
|
||||
// be fed buffers of the same size as the
|
||||
// encryptor
|
||||
|
||||
|
||||
// If the length is not a multiple of 8, I encrypt
|
||||
// the overflow to be compatible with lacy's cryptlib
|
||||
void
|
||||
des3CBCencrypt(uchar *p, int len, DES3state *s)
|
||||
{
|
||||
uchar *p2, *ip, *eip;
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
p2 = p;
|
||||
ip = s->ivec;
|
||||
for(eip = ip+8; ip < eip; )
|
||||
*p2++ ^= *ip++;
|
||||
triple_block_cipher(s->expanded, p, DES3EDE);
|
||||
memmove(s->ivec, p, 8);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
ip = s->ivec;
|
||||
triple_block_cipher(s->expanded, ip, DES3EDE);
|
||||
for(eip = ip+len; ip < eip; )
|
||||
*p++ ^= *ip++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
des3CBCdecrypt(uchar *p, int len, DES3state *s)
|
||||
{
|
||||
uchar *ip, *eip, *tp;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
memmove(tmp, p, 8);
|
||||
triple_block_cipher(s->expanded, p, DES3DED);
|
||||
tp = tmp;
|
||||
ip = s->ivec;
|
||||
for(eip = ip+8; ip < eip; ){
|
||||
*p++ ^= *ip;
|
||||
*ip++ = *tp++;
|
||||
}
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
ip = s->ivec;
|
||||
triple_block_cipher(s->expanded, ip, DES3EDE);
|
||||
for(eip = ip+len; ip < eip; )
|
||||
*p++ ^= *ip++;
|
||||
}
|
||||
}
|
48
libsec/des3ECB.c
Normal file
48
libsec/des3ECB.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// I wasn't sure what to do when the buffer was not
|
||||
// a multiple of 8. I did what lacy's cryptolib did
|
||||
// to be compatible, but it looks dangerous to me
|
||||
// since its encrypting plain text with the key. -- presotto
|
||||
|
||||
void
|
||||
des3ECBencrypt(uchar *p, int len, DES3state *s)
|
||||
{
|
||||
int i;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
triple_block_cipher(s->expanded, p, DES3EDE);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
for (i=0; i<8; i++)
|
||||
tmp[i] = i;
|
||||
triple_block_cipher(s->expanded, tmp, DES3EDE);
|
||||
for (i = 0; i < len; i++)
|
||||
p[i] ^= tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
des3ECBdecrypt(uchar *p, int len, DES3state *s)
|
||||
{
|
||||
int i;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
triple_block_cipher(s->expanded, p, DES3DED);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
for (i=0; i<8; i++)
|
||||
tmp[i] = i;
|
||||
triple_block_cipher(s->expanded, tmp, DES3EDE);
|
||||
for (i = 0; i < len; i++)
|
||||
p[i] ^= tmp[i];
|
||||
}
|
||||
}
|
59
libsec/desCBC.c
Normal file
59
libsec/desCBC.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// Because of the way that non multiple of 8
|
||||
// buffers are handled, the decryptor must
|
||||
// be fed buffers of the same size as the
|
||||
// encryptor
|
||||
|
||||
|
||||
// If the length is not a multiple of 8, I encrypt
|
||||
// the overflow to be compatible with lacy's cryptlib
|
||||
void
|
||||
desCBCencrypt(uchar *p, int len, DESstate *s)
|
||||
{
|
||||
uchar *p2, *ip, *eip;
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
p2 = p;
|
||||
ip = s->ivec;
|
||||
for(eip = ip+8; ip < eip; )
|
||||
*p2++ ^= *ip++;
|
||||
block_cipher(s->expanded, p, 0);
|
||||
memmove(s->ivec, p, 8);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
ip = s->ivec;
|
||||
block_cipher(s->expanded, ip, 0);
|
||||
for(eip = ip+len; ip < eip; )
|
||||
*p++ ^= *ip++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
desCBCdecrypt(uchar *p, int len, DESstate *s)
|
||||
{
|
||||
uchar *ip, *eip, *tp;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
memmove(tmp, p, 8);
|
||||
block_cipher(s->expanded, p, 1);
|
||||
tp = tmp;
|
||||
ip = s->ivec;
|
||||
for(eip = ip+8; ip < eip; ){
|
||||
*p++ ^= *ip;
|
||||
*ip++ = *tp++;
|
||||
}
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
ip = s->ivec;
|
||||
block_cipher(s->expanded, ip, 0);
|
||||
for(eip = ip+len; ip < eip; )
|
||||
*p++ ^= *ip++;
|
||||
}
|
||||
}
|
48
libsec/desECB.c
Normal file
48
libsec/desECB.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// I wasn't sure what to do when the buffer was not
|
||||
// a multiple of 8. I did what lacy's cryptolib did
|
||||
// to be compatible, but it looks dangerous to me
|
||||
// since its encrypting plain text with the key. -- presotto
|
||||
|
||||
void
|
||||
desECBencrypt(uchar *p, int len, DESstate *s)
|
||||
{
|
||||
int i;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
block_cipher(s->expanded, p, 0);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
for (i=0; i<8; i++)
|
||||
tmp[i] = i;
|
||||
block_cipher(s->expanded, tmp, 0);
|
||||
for (i = 0; i < len; i++)
|
||||
p[i] ^= tmp[i];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
desECBdecrypt(uchar *p, int len, DESstate *s)
|
||||
{
|
||||
int i;
|
||||
uchar tmp[8];
|
||||
|
||||
for(; len >= 8; len -= 8){
|
||||
block_cipher(s->expanded, p, 1);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if(len > 0){
|
||||
for (i=0; i<8; i++)
|
||||
tmp[i] = i;
|
||||
block_cipher(s->expanded, tmp, 0);
|
||||
for (i = 0; i < len; i++)
|
||||
p[i] ^= tmp[i];
|
||||
}
|
||||
}
|
31
libsec/desmodes.c
Normal file
31
libsec/desmodes.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* these routines use the 64bit format for
|
||||
* DES keys.
|
||||
*/
|
||||
|
||||
void
|
||||
setupDESstate(DESstate *s, uchar key[8], uchar *ivec)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
memmove(s->key, key, sizeof(s->key));
|
||||
des_key_setup(key, s->expanded);
|
||||
if(ivec)
|
||||
memmove(s->ivec, ivec, 8);
|
||||
s->setup = 0xdeadbeef;
|
||||
}
|
||||
|
||||
void
|
||||
setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
memmove(s->key, key, sizeof(s->key));
|
||||
des_key_setup(key[0], s->expanded[0]);
|
||||
des_key_setup(key[1], s->expanded[1]);
|
||||
des_key_setup(key[2], s->expanded[2]);
|
||||
if(ivec)
|
||||
memmove(s->ivec, ivec, 8);
|
||||
s->setup = 0xdeadbeef;
|
||||
}
|
69
libsec/dsaalloc.c
Normal file
69
libsec/dsaalloc.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
DSApub*
|
||||
dsapuballoc(void)
|
||||
{
|
||||
DSApub *dsa;
|
||||
|
||||
dsa = mallocz(sizeof(*dsa), 1);
|
||||
if(dsa == nil)
|
||||
sysfatal("dsapuballoc");
|
||||
return dsa;
|
||||
}
|
||||
|
||||
void
|
||||
dsapubfree(DSApub *dsa)
|
||||
{
|
||||
if(dsa == nil)
|
||||
return;
|
||||
mpfree(dsa->p);
|
||||
mpfree(dsa->q);
|
||||
mpfree(dsa->alpha);
|
||||
mpfree(dsa->key);
|
||||
}
|
||||
|
||||
|
||||
DSApriv*
|
||||
dsaprivalloc(void)
|
||||
{
|
||||
DSApriv *dsa;
|
||||
|
||||
dsa = mallocz(sizeof(*dsa), 1);
|
||||
if(dsa == nil)
|
||||
sysfatal("dsaprivalloc");
|
||||
return dsa;
|
||||
}
|
||||
|
||||
void
|
||||
dsaprivfree(DSApriv *dsa)
|
||||
{
|
||||
if(dsa == nil)
|
||||
return;
|
||||
mpfree(dsa->pub.p);
|
||||
mpfree(dsa->pub.q);
|
||||
mpfree(dsa->pub.alpha);
|
||||
mpfree(dsa->pub.key);
|
||||
mpfree(dsa->secret);
|
||||
}
|
||||
|
||||
DSAsig*
|
||||
dsasigalloc(void)
|
||||
{
|
||||
DSAsig *dsa;
|
||||
|
||||
dsa = mallocz(sizeof(*dsa), 1);
|
||||
if(dsa == nil)
|
||||
sysfatal("dsasigalloc");
|
||||
return dsa;
|
||||
}
|
||||
|
||||
void
|
||||
dsasigfree(DSAsig *dsa)
|
||||
{
|
||||
if(dsa == nil)
|
||||
return;
|
||||
mpfree(dsa->r);
|
||||
mpfree(dsa->s);
|
||||
}
|
61
libsec/dsagen.c
Normal file
61
libsec/dsagen.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
DSApriv*
|
||||
dsagen(DSApub *opub)
|
||||
{
|
||||
DSApub *pub;
|
||||
DSApriv *priv;
|
||||
mpint *exp;
|
||||
mpint *g;
|
||||
mpint *r;
|
||||
int bits;
|
||||
|
||||
priv = dsaprivalloc();
|
||||
pub = &priv->pub;
|
||||
|
||||
if(opub != nil){
|
||||
pub->p = mpcopy(opub->p);
|
||||
pub->q = mpcopy(opub->q);
|
||||
} else {
|
||||
pub->p = mpnew(0);
|
||||
pub->q = mpnew(0);
|
||||
DSAprimes(pub->q, pub->p, nil);
|
||||
}
|
||||
bits = Dbits*pub->p->top;
|
||||
|
||||
pub->alpha = mpnew(0);
|
||||
pub->key = mpnew(0);
|
||||
priv->secret = mpnew(0);
|
||||
|
||||
// find a generator alpha of the multiplicative
|
||||
// group Z*p, i.e., of order n = p-1. We use the
|
||||
// fact that q divides p-1 to reduce the exponent.
|
||||
//
|
||||
// This isn't very efficient. If anyone has a better
|
||||
// idea, mail presotto@closedmind.org
|
||||
exp = mpnew(0);
|
||||
g = mpnew(0);
|
||||
r = mpnew(0);
|
||||
mpsub(pub->p, mpone, exp);
|
||||
mpdiv(exp, pub->q, exp, r);
|
||||
if(mpcmp(r, mpzero) != 0)
|
||||
sysfatal("dsagen foul up");
|
||||
while(1){
|
||||
mprand(bits, genrandom, g);
|
||||
mpmod(g, pub->p, g);
|
||||
mpexp(g, exp, pub->p, pub->alpha);
|
||||
if(mpcmp(pub->alpha, mpone) != 0)
|
||||
break;
|
||||
}
|
||||
mpfree(g);
|
||||
mpfree(exp);
|
||||
|
||||
// create the secret key
|
||||
mprand(bits, genrandom, priv->secret);
|
||||
mpmod(priv->secret, pub->p, priv->secret);
|
||||
mpexp(pub->alpha, priv->secret, pub->p, pub->key);
|
||||
|
||||
return priv;
|
||||
}
|
97
libsec/dsaprimes.c
Normal file
97
libsec/dsaprimes.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// NIST algorithm for generating DSA primes
|
||||
// Menezes et al (1997) Handbook of Applied Cryptography, p.151
|
||||
// q is a 160-bit prime; p is a 1024-bit prime; q divides p-1
|
||||
|
||||
// arithmetic on unsigned ints mod 2**160, represented
|
||||
// as 20-byte, little-endian uchar array
|
||||
|
||||
static void
|
||||
Hrand(uchar *s)
|
||||
{
|
||||
ulong *u = (ulong*)s;
|
||||
*u++ = fastrand();
|
||||
*u++ = fastrand();
|
||||
*u++ = fastrand();
|
||||
*u++ = fastrand();
|
||||
*u = fastrand();
|
||||
}
|
||||
|
||||
static void
|
||||
Hincr(uchar *s)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<20; i++)
|
||||
if(++s[i]!=0)
|
||||
break;
|
||||
}
|
||||
|
||||
// this can run for quite a while; be patient
|
||||
void
|
||||
DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen])
|
||||
{
|
||||
int i, j, k, n = 6, b = 63;
|
||||
uchar s[SHA1dlen], Hs[SHA1dlen], Hs1[SHA1dlen], sj[SHA1dlen], sjk[SHA1dlen];
|
||||
mpint *two1023, *mb, *Vk, *W, *X, *q2;
|
||||
|
||||
two1023 = mpnew(1024);
|
||||
mpleft(mpone, 1023, two1023);
|
||||
mb = mpnew(0);
|
||||
mpleft(mpone, b, mb);
|
||||
W = mpnew(1024);
|
||||
Vk = mpnew(1024);
|
||||
X = mpnew(0);
|
||||
q2 = mpnew(0);
|
||||
forever:
|
||||
do{
|
||||
Hrand(s);
|
||||
memcpy(sj, s, 20);
|
||||
sha1(s, 20, Hs, 0);
|
||||
Hincr(sj);
|
||||
sha1(sj, 20, Hs1, 0);
|
||||
for(i=0; i<20; i++)
|
||||
Hs[i] ^= Hs1[i];
|
||||
Hs[0] |= 1;
|
||||
Hs[19] |= 0x80;
|
||||
letomp(Hs, 20, q);
|
||||
}while(!probably_prime(q, 18));
|
||||
if(seed != nil) // allow skeptics to confirm computation
|
||||
memmove(seed, s, SHA1dlen);
|
||||
i = 0;
|
||||
j = 2;
|
||||
Hincr(sj);
|
||||
mpleft(q, 1, q2);
|
||||
while(i<4096){
|
||||
memcpy(sjk, sj, 20);
|
||||
for(k=0; k <= n; k++){
|
||||
sha1(sjk, 20, Hs, 0);
|
||||
letomp(Hs, 20, Vk);
|
||||
if(k == n)
|
||||
mpmod(Vk, mb, Vk);
|
||||
mpleft(Vk, 160*k, Vk);
|
||||
mpadd(W, Vk, W);
|
||||
Hincr(sjk);
|
||||
}
|
||||
mpadd(W, two1023, X);
|
||||
mpmod(X, q2, W);
|
||||
mpsub(W, mpone, W);
|
||||
mpsub(X, W, p);
|
||||
if(mpcmp(p, two1023)>=0 && probably_prime(p, 5))
|
||||
goto done;
|
||||
i += 1;
|
||||
j += n+1;
|
||||
for(k=0; k<n+1; k++)
|
||||
Hincr(sj);
|
||||
}
|
||||
goto forever;
|
||||
done:
|
||||
mpfree(q2);
|
||||
mpfree(X);
|
||||
mpfree(Vk);
|
||||
mpfree(W);
|
||||
mpfree(mb);
|
||||
mpfree(two1023);
|
||||
}
|
16
libsec/dsaprivtopub.c
Normal file
16
libsec/dsaprivtopub.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
DSApub*
|
||||
dsaprivtopub(DSApriv *priv)
|
||||
{
|
||||
DSApub *pub;
|
||||
|
||||
pub = dsapuballoc();
|
||||
pub->p = mpcopy(priv->pub.p);
|
||||
pub->q = mpcopy(priv->pub.q);
|
||||
pub->alpha = mpcopy(priv->pub.alpha);
|
||||
pub->key = mpcopy(priv->pub.key);
|
||||
return pub;
|
||||
}
|
52
libsec/dsasign.c
Normal file
52
libsec/dsasign.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
DSAsig*
|
||||
dsasign(DSApriv *priv, mpint *m)
|
||||
{
|
||||
DSApub *pub = &priv->pub;
|
||||
DSAsig *sig;
|
||||
mpint *qm1, *k, *kinv, *r, *s;
|
||||
mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
|
||||
int qlen = mpsignif(q);
|
||||
|
||||
qm1 = mpnew(0);
|
||||
kinv = mpnew(0);
|
||||
r = mpnew(0);
|
||||
s = mpnew(0);
|
||||
k = mpnew(0);
|
||||
mpsub(pub->q, mpone, qm1);
|
||||
|
||||
// find a k that has an inverse mod q
|
||||
while(1){
|
||||
mprand(qlen, genrandom, k);
|
||||
if((mpcmp(mpone, k) > 0) || (mpcmp(k, qm1) >= 0))
|
||||
continue;
|
||||
mpextendedgcd(k, q, r, kinv, s);
|
||||
if(mpcmp(r, mpone) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
// make kinv positive
|
||||
mpmod(kinv, qm1, kinv);
|
||||
|
||||
// r = ((alpha**k) mod p) mod q
|
||||
mpexp(alpha, k, p, r);
|
||||
mpmod(r, q, r);
|
||||
|
||||
// s = (kinv*(m + ar)) mod q
|
||||
mpmul(r, priv->secret, s);
|
||||
mpadd(s, m, s);
|
||||
mpmul(s, kinv, s);
|
||||
mpmod(s, q, s);
|
||||
|
||||
sig = dsasigalloc();
|
||||
sig->r = r;
|
||||
sig->s = s;
|
||||
mpfree(qm1);
|
||||
mpfree(k);
|
||||
mpfree(kinv);
|
||||
return sig;
|
||||
}
|
46
libsec/dsaverify.c
Normal file
46
libsec/dsaverify.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
int
|
||||
dsaverify(DSApub *pub, DSAsig *sig, mpint *m)
|
||||
{
|
||||
int rv = -1;
|
||||
mpint *u1, *u2, *v, *sinv;
|
||||
|
||||
if(sig->r->sign < 0 || mpcmp(sig->r, pub->q) >= 0)
|
||||
return rv;
|
||||
if(sig->s->sign < 0 || mpcmp(sig->s, pub->q) >= 0)
|
||||
return rv;
|
||||
u1 = mpnew(0);
|
||||
u2 = mpnew(0);
|
||||
v = mpnew(0);
|
||||
sinv = mpnew(0);
|
||||
|
||||
// find (s**-1) mod q, make sure it exists
|
||||
mpextendedgcd(sig->s, pub->q, u1, sinv, v);
|
||||
if(mpcmp(u1, mpone) != 0)
|
||||
goto out;
|
||||
|
||||
// u1 = (sinv * m) mod q, u2 = (r * sinv) mod q
|
||||
mpmul(sinv, m, u1);
|
||||
mpmod(u1, pub->q, u1);
|
||||
mpmul(sig->r, sinv, u2);
|
||||
mpmod(u2, pub->q, u2);
|
||||
|
||||
// v = (((alpha**u1)*(key**u2)) mod p) mod q
|
||||
mpexp(pub->alpha, u1, pub->p, sinv);
|
||||
mpexp(pub->key, u2, pub->p, v);
|
||||
mpmul(sinv, v, v);
|
||||
mpmod(v, pub->p, v);
|
||||
mpmod(v, pub->q, v);
|
||||
|
||||
if(mpcmp(v, sig->r) == 0)
|
||||
rv = 0;
|
||||
out:
|
||||
mpfree(v);
|
||||
mpfree(u1);
|
||||
mpfree(u2);
|
||||
mpfree(sinv);
|
||||
return rv;
|
||||
}
|
67
libsec/egalloc.c
Normal file
67
libsec/egalloc.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
EGpub*
|
||||
egpuballoc(void)
|
||||
{
|
||||
EGpub *eg;
|
||||
|
||||
eg = mallocz(sizeof(*eg), 1);
|
||||
if(eg == nil)
|
||||
sysfatal("egpuballoc");
|
||||
return eg;
|
||||
}
|
||||
|
||||
void
|
||||
egpubfree(EGpub *eg)
|
||||
{
|
||||
if(eg == nil)
|
||||
return;
|
||||
mpfree(eg->p);
|
||||
mpfree(eg->alpha);
|
||||
mpfree(eg->key);
|
||||
}
|
||||
|
||||
|
||||
EGpriv*
|
||||
egprivalloc(void)
|
||||
{
|
||||
EGpriv *eg;
|
||||
|
||||
eg = mallocz(sizeof(*eg), 1);
|
||||
if(eg == nil)
|
||||
sysfatal("egprivalloc");
|
||||
return eg;
|
||||
}
|
||||
|
||||
void
|
||||
egprivfree(EGpriv *eg)
|
||||
{
|
||||
if(eg == nil)
|
||||
return;
|
||||
mpfree(eg->pub.p);
|
||||
mpfree(eg->pub.alpha);
|
||||
mpfree(eg->pub.key);
|
||||
mpfree(eg->secret);
|
||||
}
|
||||
|
||||
EGsig*
|
||||
egsigalloc(void)
|
||||
{
|
||||
EGsig *eg;
|
||||
|
||||
eg = mallocz(sizeof(*eg), 1);
|
||||
if(eg == nil)
|
||||
sysfatal("egsigalloc");
|
||||
return eg;
|
||||
}
|
||||
|
||||
void
|
||||
egsigfree(EGsig *eg)
|
||||
{
|
||||
if(eg == nil)
|
||||
return;
|
||||
mpfree(eg->r);
|
||||
mpfree(eg->s);
|
||||
}
|
28
libsec/egdecrypt.c
Normal file
28
libsec/egdecrypt.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
mpint*
|
||||
egdecrypt(EGpriv *priv, mpint *in, mpint *out)
|
||||
{
|
||||
EGpub *pub = &priv->pub;
|
||||
mpint *gamma, *delta;
|
||||
mpint *p = pub->p;
|
||||
int plen = mpsignif(p)+1;
|
||||
int shift = ((plen+Dbits-1)/Dbits)*Dbits;
|
||||
|
||||
if(out == nil)
|
||||
out = mpnew(0);
|
||||
gamma = mpnew(0);
|
||||
delta = mpnew(0);
|
||||
mpright(in, shift, gamma);
|
||||
mpleft(gamma, shift, delta);
|
||||
mpsub(in, delta, delta);
|
||||
mpexp(gamma, priv->secret, p, out);
|
||||
mpinvert(out, p, gamma);
|
||||
mpmul(gamma, delta, out);
|
||||
mpmod(out, p, out);
|
||||
mpfree(gamma);
|
||||
mpfree(delta);
|
||||
return out;
|
||||
}
|
38
libsec/egencrypt.c
Normal file
38
libsec/egencrypt.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
mpint*
|
||||
egencrypt(EGpub *pub, mpint *in, mpint *out)
|
||||
{
|
||||
mpint *m, *k, *gamma, *delta, *pm1;
|
||||
mpint *p = pub->p, *alpha = pub->alpha;
|
||||
int plen = mpsignif(p);
|
||||
int shift = ((plen+Dbits)/Dbits)*Dbits;
|
||||
// in libcrypt version, (int)(LENGTH(pub->p)*sizeof(NumType)*CHARBITS);
|
||||
|
||||
if(out == nil)
|
||||
out = mpnew(0);
|
||||
pm1 = mpnew(0);
|
||||
m = mpnew(0);
|
||||
gamma = mpnew(0);
|
||||
delta = mpnew(0);
|
||||
mpmod(in, p, m);
|
||||
while(1){
|
||||
k = mprand(plen, genrandom, nil);
|
||||
if((mpcmp(mpone, k) <= 0) && (mpcmp(k, pm1) < 0))
|
||||
break;
|
||||
}
|
||||
mpexp(alpha, k, p, gamma);
|
||||
mpexp(pub->key, k, p, delta);
|
||||
mpmul(m, delta, delta);
|
||||
mpmod(delta, p, delta);
|
||||
mpleft(gamma, shift, out);
|
||||
mpadd(delta, out, out);
|
||||
mpfree(pm1);
|
||||
mpfree(m);
|
||||
mpfree(k);
|
||||
mpfree(gamma);
|
||||
mpfree(delta);
|
||||
return out;
|
||||
}
|
21
libsec/eggen.c
Normal file
21
libsec/eggen.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
EGpriv*
|
||||
eggen(int nlen, int rounds)
|
||||
{
|
||||
EGpub *pub;
|
||||
EGpriv *priv;
|
||||
|
||||
priv = egprivalloc();
|
||||
pub = &priv->pub;
|
||||
pub->p = mpnew(0);
|
||||
pub->alpha = mpnew(0);
|
||||
pub->key = mpnew(0);
|
||||
priv->secret = mpnew(0);
|
||||
gensafeprime(pub->p, pub->alpha, nlen, rounds);
|
||||
mprand(nlen-1, genrandom, priv->secret);
|
||||
mpexp(pub->alpha, priv->secret, pub->p, pub->key);
|
||||
return priv;
|
||||
}
|
17
libsec/egprivtopub.c
Normal file
17
libsec/egprivtopub.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
EGpub*
|
||||
egprivtopub(EGpriv *priv)
|
||||
{
|
||||
EGpub *pub;
|
||||
|
||||
pub = egpuballoc();
|
||||
if(pub == nil)
|
||||
return nil;
|
||||
pub->p = mpcopy(priv->pub.p);
|
||||
pub->alpha = mpcopy(priv->pub.alpha);
|
||||
pub->key = mpcopy(priv->pub.key);
|
||||
return pub;
|
||||
}
|
43
libsec/egsign.c
Normal file
43
libsec/egsign.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
EGsig*
|
||||
egsign(EGpriv *priv, mpint *m)
|
||||
{
|
||||
EGpub *pub = &priv->pub;
|
||||
EGsig *sig;
|
||||
mpint *pm1, *k, *kinv, *r, *s;
|
||||
mpint *p = pub->p, *alpha = pub->alpha;
|
||||
int plen = mpsignif(p);
|
||||
|
||||
pm1 = mpnew(0);
|
||||
kinv = mpnew(0);
|
||||
r = mpnew(0);
|
||||
s = mpnew(0);
|
||||
k = mpnew(0);
|
||||
mpsub(p, mpone, pm1);
|
||||
while(1){
|
||||
mprand(plen, genrandom, k);
|
||||
if((mpcmp(mpone, k) > 0) || (mpcmp(k, pm1) >= 0))
|
||||
continue;
|
||||
mpextendedgcd(k, pm1, r, kinv, s);
|
||||
if(mpcmp(r, mpone) != 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
mpmod(kinv, pm1, kinv); // make kinv positive
|
||||
mpexp(alpha, k, p, r);
|
||||
mpmul(priv->secret, r, s);
|
||||
mpmod(s, pm1, s);
|
||||
mpsub(m, s, s);
|
||||
mpmul(kinv, s, s);
|
||||
mpmod(s, pm1, s);
|
||||
sig = egsigalloc();
|
||||
sig->r = r;
|
||||
sig->s = s;
|
||||
mpfree(pm1);
|
||||
mpfree(k);
|
||||
mpfree(kinv);
|
||||
return sig;
|
||||
}
|
34
libsec/egtest.c
Normal file
34
libsec/egtest.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
EGpriv *sk;
|
||||
mpint *m, *gamma, *delta, *in, *out;
|
||||
int plen, shift;
|
||||
|
||||
fmtinstall('B', mpconv);
|
||||
|
||||
sk = egprivalloc();
|
||||
sk->pub.p = uitomp(2357, nil);
|
||||
sk->pub.alpha = uitomp(2, nil);
|
||||
sk->pub.key = uitomp(1185, nil);
|
||||
sk->secret = uitomp(1751, nil);
|
||||
|
||||
m = uitomp(2035, nil);
|
||||
|
||||
plen = mpsignif(sk->pub.p)+1;
|
||||
shift = ((plen+Dbits-1)/Dbits)*Dbits;
|
||||
gamma = uitomp(1430, nil);
|
||||
delta = uitomp(697, nil);
|
||||
out = mpnew(0);
|
||||
in = mpnew(0);
|
||||
mpleft(gamma, shift, in);
|
||||
mpadd(delta, in, in);
|
||||
egdecrypt(sk, in, out);
|
||||
|
||||
if(mpcmp(m, out) != 0)
|
||||
print("decrypt failed to recover message\n");
|
||||
}
|
29
libsec/egverify.c
Normal file
29
libsec/egverify.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
int
|
||||
egverify(EGpub *pub, EGsig *sig, mpint *m)
|
||||
{
|
||||
mpint *p = pub->p, *alpha = pub->alpha;
|
||||
mpint *r = sig->r, *s = sig->s;
|
||||
mpint *v1, *v2, *rs;
|
||||
int rv = -1;
|
||||
|
||||
if(mpcmp(r, mpone) < 0 || mpcmp(r, p) >= 0)
|
||||
return rv;
|
||||
v1 = mpnew(0);
|
||||
rs = mpnew(0);
|
||||
v2 = mpnew(0);
|
||||
mpexp(pub->key, r, p, v1);
|
||||
mpexp(r, s, p, rs);
|
||||
mpmul(v1, rs, v1);
|
||||
mpmod(v1, p, v1);
|
||||
mpexp(alpha, m, p, v2);
|
||||
if(mpcmp(v1, v2) == 0)
|
||||
rv = 0;
|
||||
mpfree(v1);
|
||||
mpfree(rs);
|
||||
mpfree(v2);
|
||||
return rv;
|
||||
}
|
16
libsec/fastrand.c
Normal file
16
libsec/fastrand.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* use the X917 random number generator to create random
|
||||
* numbers (faster than truerand() but not as random).
|
||||
*/
|
||||
ulong
|
||||
fastrand(void)
|
||||
{
|
||||
ulong x;
|
||||
|
||||
genrandom((uchar*)&x, sizeof x);
|
||||
return x;
|
||||
}
|
27
libsec/genprime.c
Normal file
27
libsec/genprime.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// generate a probable prime. accuracy is the miller-rabin interations
|
||||
void
|
||||
genprime(mpint *p, int n, int accuracy)
|
||||
{
|
||||
mpdigit x;
|
||||
|
||||
// generate n random bits with high and low bits set
|
||||
mpbits(p, n);
|
||||
genrandom((uchar*)p->p, (n+7)/8);
|
||||
p->top = (n+Dbits-1)/Dbits;
|
||||
x = 1;
|
||||
x <<= ((n-1)%Dbits);
|
||||
p->p[p->top-1] &= (x-1);
|
||||
p->p[p->top-1] |= x;
|
||||
p->p[0] |= 1;
|
||||
|
||||
// keep icrementing till it looks prime
|
||||
for(;;){
|
||||
if(probably_prime(p, accuracy))
|
||||
break;
|
||||
mpadd(p, mptwo, p);
|
||||
}
|
||||
}
|
62
libsec/genrandom.c
Normal file
62
libsec/genrandom.c
Normal file
@ -0,0 +1,62 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
typedef struct State{
|
||||
QLock lock;
|
||||
int seeded;
|
||||
uvlong seed;
|
||||
DES3state des3;
|
||||
} State;
|
||||
static State x917state;
|
||||
|
||||
static void
|
||||
X917(uchar *rand, int nrand)
|
||||
{
|
||||
int i, m, n8;
|
||||
uvlong I, x;
|
||||
|
||||
/* 1. Compute intermediate value I = Ek(time). */
|
||||
I = nsec();
|
||||
triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */
|
||||
|
||||
/* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */
|
||||
m = (nrand+7)/8;
|
||||
for(i=0; i<m; i++){
|
||||
x = I ^ x917state.seed;
|
||||
triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
|
||||
n8 = (nrand>8) ? 8 : nrand;
|
||||
memcpy(rand, (uchar*)&x, n8);
|
||||
rand += 8;
|
||||
nrand -= 8;
|
||||
x ^= I;
|
||||
triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0);
|
||||
x917state.seed = x;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
X917init(void)
|
||||
{
|
||||
int n;
|
||||
uchar mix[128];
|
||||
uchar key3[3][8];
|
||||
ulong *ulp;
|
||||
|
||||
ulp = (ulong*)key3;
|
||||
for(n = 0; n < sizeof(key3)/sizeof(ulong); n++)
|
||||
ulp[n] = truerand();
|
||||
setupDES3state(&x917state.des3, key3, nil);
|
||||
X917(mix, sizeof mix);
|
||||
x917state.seeded = 1;
|
||||
}
|
||||
|
||||
void
|
||||
genrandom(uchar *p, int n)
|
||||
{
|
||||
qlock(&x917state.lock);
|
||||
if(x917state.seeded == 0)
|
||||
X917init();
|
||||
X917(p, n);
|
||||
qunlock(&x917state.lock);
|
||||
}
|
36
libsec/gensafeprime.c
Normal file
36
libsec/gensafeprime.c
Normal file
@ -0,0 +1,36 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// find a prime p of length n and a generator alpha of Z^*_p
|
||||
// Alg 4.86 Menezes et al () Handbook, p.164
|
||||
void
|
||||
gensafeprime(mpint *p, mpint *alpha, int n, int accuracy)
|
||||
{
|
||||
mpint *q, *b;
|
||||
|
||||
q = mpnew(n-1);
|
||||
while(1){
|
||||
genprime(q, n-1, accuracy);
|
||||
mpleft(q, 1, p);
|
||||
mpadd(p, mpone, p); // p = 2*q+1
|
||||
if(probably_prime(p, accuracy))
|
||||
break;
|
||||
}
|
||||
// now find a generator alpha of the multiplicative
|
||||
// group Z*_p of order p-1=2q
|
||||
b = mpnew(0);
|
||||
while(1){
|
||||
mprand(n, genrandom, alpha);
|
||||
mpmod(alpha, p, alpha);
|
||||
mpmul(alpha, alpha, b);
|
||||
mpmod(b, p, b);
|
||||
if(mpcmp(b, mpone) == 0)
|
||||
continue;
|
||||
mpexp(alpha, q, p, b);
|
||||
if(mpcmp(b, mpone) != 0)
|
||||
break;
|
||||
}
|
||||
mpfree(b);
|
||||
mpfree(q);
|
||||
}
|
57
libsec/genstrongprime.c
Normal file
57
libsec/genstrongprime.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// Gordon's algorithm for generating a strong prime
|
||||
// Menezes et al () Handbook, p.150
|
||||
void
|
||||
genstrongprime(mpint *p, int n, int accuracy)
|
||||
{
|
||||
mpint *s, *t, *r, *i;
|
||||
|
||||
if(n < 64)
|
||||
n = 64;
|
||||
|
||||
s = mpnew(n/2);
|
||||
genprime(s, (n/2)-16, accuracy);
|
||||
t = mpnew(n/2);
|
||||
genprime(t, n-mpsignif(s)-32, accuracy);
|
||||
|
||||
// first r = 2it + 1 that's prime
|
||||
i = mpnew(16);
|
||||
r = mpnew(0);
|
||||
itomp(0x8000, i);
|
||||
mpleft(t, 1, t); // 2t
|
||||
mpmul(i, t, r); // 2it
|
||||
mpadd(r, mpone, r); // 2it + 1
|
||||
for(;;){
|
||||
if(probably_prime(r, 18))
|
||||
break;
|
||||
mpadd(r, t, r); // r += 2t
|
||||
}
|
||||
|
||||
// p0 = 2(s**(r-2) mod r)s - 1
|
||||
itomp(2, p);
|
||||
mpsub(r, p, p);
|
||||
mpexp(s, p, r, p);
|
||||
mpmul(s, p, p);
|
||||
mpleft(p, 1, p);
|
||||
mpsub(p, mpone, p);
|
||||
|
||||
// first p = p0 + 2irs that's prime
|
||||
itomp(0x8000, i);
|
||||
mpleft(r, 1, r); // 2r
|
||||
mpmul(r, s, r); // 2rs
|
||||
mpmul(r, i, i); // 2irs
|
||||
mpadd(p, i, p); // p0 + 2irs
|
||||
for(;;){
|
||||
if(probably_prime(p, accuracy))
|
||||
break;
|
||||
mpadd(p, r, p); // p += 2rs
|
||||
}
|
||||
|
||||
mpfree(i);
|
||||
mpfree(s);
|
||||
mpfree(r);
|
||||
mpfree(t);
|
||||
}
|
56
libsec/hmac.c
Normal file
56
libsec/hmac.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/* rfc2104 */
|
||||
static DigestState*
|
||||
hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s,
|
||||
DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen)
|
||||
{
|
||||
int i;
|
||||
uchar pad[65], innerdigest[256];
|
||||
|
||||
if(xlen > sizeof(innerdigest))
|
||||
return nil;
|
||||
|
||||
if(klen>64)
|
||||
return nil;
|
||||
|
||||
/* first time through */
|
||||
if(s == nil){
|
||||
for(i=0; i<64; i++)
|
||||
pad[i] = 0x36;
|
||||
pad[64] = 0;
|
||||
for(i=0; i<klen; i++)
|
||||
pad[i] ^= key[i];
|
||||
s = (*x)(pad, 64, nil, nil);
|
||||
if(s == nil)
|
||||
return nil;
|
||||
}
|
||||
|
||||
s = (*x)(p, len, nil, s);
|
||||
if(digest == nil)
|
||||
return s;
|
||||
|
||||
/* last time through */
|
||||
for(i=0; i<64; i++)
|
||||
pad[i] = 0x5c;
|
||||
pad[64] = 0;
|
||||
for(i=0; i<klen; i++)
|
||||
pad[i] ^= key[i];
|
||||
(*x)(nil, 0, innerdigest, s);
|
||||
s = (*x)(pad, 64, nil, nil);
|
||||
(*x)(innerdigest, xlen, digest, s);
|
||||
return nil;
|
||||
}
|
||||
|
||||
DigestState*
|
||||
hmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
|
||||
{
|
||||
return hmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen);
|
||||
}
|
||||
|
||||
DigestState*
|
||||
hmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
|
||||
{
|
||||
return hmac_x(p, len, key, klen, digest, s, md5, MD5dlen);
|
||||
}
|
19
libsec/hmactest.c
Normal file
19
libsec/hmactest.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
uchar key[] = "Jefe";
|
||||
uchar data[] = "what do ya want for nothing?";
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
int i;
|
||||
uchar hash[MD5dlen];
|
||||
|
||||
hmac_md5(data, strlen((char*)data), key, 4, hash, nil);
|
||||
for(i=0; i<MD5dlen; i++)
|
||||
print("%2.2x", hash[i]);
|
||||
print("\n");
|
||||
print("750c783e6ab0b503eaa86e310a5db738\n");
|
||||
}
|
271
libsec/md4.c
Normal file
271
libsec/md4.c
Normal file
@ -0,0 +1,271 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* This MD4 is implemented from the description in Stinson's Cryptography,
|
||||
* theory and practice. -- presotto
|
||||
*/
|
||||
|
||||
/*
|
||||
* Rotate ammounts used in the algorithm
|
||||
*/
|
||||
enum
|
||||
{
|
||||
S11= 3,
|
||||
S12= 7,
|
||||
S13= 11,
|
||||
S14= 19,
|
||||
|
||||
S21= 3,
|
||||
S22= 5,
|
||||
S23= 9,
|
||||
S24= 13,
|
||||
|
||||
S31= 3,
|
||||
S32= 9,
|
||||
S33= 11,
|
||||
S34= 15,
|
||||
};
|
||||
|
||||
typedef struct MD4Table MD4Table;
|
||||
struct MD4Table
|
||||
{
|
||||
uchar x; /* index into data block */
|
||||
uchar rot; /* amount to rotate left by */
|
||||
};
|
||||
|
||||
static MD4Table tab[] =
|
||||
{
|
||||
/* round 1 */
|
||||
/*[0]*/ { 0, S11},
|
||||
{ 1, S12},
|
||||
{ 2, S13},
|
||||
{ 3, S14},
|
||||
{ 4, S11},
|
||||
{ 5, S12},
|
||||
{ 6, S13},
|
||||
{ 7, S14},
|
||||
{ 8, S11},
|
||||
{ 9, S12},
|
||||
{ 10, S13},
|
||||
{ 11, S14},
|
||||
{ 12, S11},
|
||||
{ 13, S12},
|
||||
{ 14, S13},
|
||||
{ 15, S14},
|
||||
|
||||
/* round 2 */
|
||||
/*[16]*/{ 0, S21},
|
||||
{ 4, S22},
|
||||
{ 8, S23},
|
||||
{ 12, S24},
|
||||
{ 1, S21},
|
||||
{ 5, S22},
|
||||
{ 9, S23},
|
||||
{ 13, S24},
|
||||
{ 2, S21},
|
||||
{ 6, S22},
|
||||
{ 10, S23},
|
||||
{ 14, S24},
|
||||
{ 3, S21},
|
||||
{ 7, S22},
|
||||
{ 11, S23},
|
||||
{ 15, S24},
|
||||
|
||||
/* round 3 */
|
||||
/*[32]*/{ 0, S31},
|
||||
{ 8, S32},
|
||||
{ 4, S33},
|
||||
{ 12, S34},
|
||||
{ 2, S31},
|
||||
{ 10, S32},
|
||||
{ 6, S33},
|
||||
{ 14, S34},
|
||||
{ 1, S31},
|
||||
{ 9, S32},
|
||||
{ 5, S33},
|
||||
{ 13, S34},
|
||||
{ 3, S31},
|
||||
{ 11, S32},
|
||||
{ 7, S33},
|
||||
{ 15, S34},
|
||||
};
|
||||
|
||||
static void encode(uchar*, u32int*, ulong);
|
||||
static void decode(u32int*, uchar*, ulong);
|
||||
|
||||
static void
|
||||
md4block(uchar *p, ulong len, MD4state *s)
|
||||
{
|
||||
int i;
|
||||
u32int a, b, c, d, tmp;
|
||||
MD4Table *t;
|
||||
uchar *end;
|
||||
u32int x[16];
|
||||
|
||||
for(end = p+len; p < end; p += 64){
|
||||
a = s->state[0];
|
||||
b = s->state[1];
|
||||
c = s->state[2];
|
||||
d = s->state[3];
|
||||
|
||||
decode(x, p, 64);
|
||||
|
||||
for(i = 0; i < 48; i++){
|
||||
t = tab + i;
|
||||
switch(i>>4){
|
||||
case 0:
|
||||
a += (b & c) | (~b & d);
|
||||
break;
|
||||
case 1:
|
||||
a += ((b & c) | (b & d) | (c & d)) + 0x5A827999;
|
||||
break;
|
||||
case 2:
|
||||
a += (b ^ c ^ d) + 0x6ED9EBA1;
|
||||
break;
|
||||
}
|
||||
a += x[t->x];
|
||||
a = (a << t->rot) | (a >> (32 - t->rot));
|
||||
|
||||
/* rotate variables */
|
||||
tmp = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = tmp;
|
||||
}
|
||||
|
||||
s->state[0] += a;
|
||||
s->state[1] += b;
|
||||
s->state[2] += c;
|
||||
s->state[3] += d;
|
||||
|
||||
s->len += 64;
|
||||
}
|
||||
}
|
||||
|
||||
MD4state*
|
||||
md4(uchar *p, ulong len, uchar *digest, MD4state *s)
|
||||
{
|
||||
u32int x[16];
|
||||
uchar buf[128];
|
||||
int i;
|
||||
uchar *e;
|
||||
|
||||
if(s == nil){
|
||||
s = malloc(sizeof(*s));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->malloced = 1;
|
||||
}
|
||||
|
||||
if(s->seeded == 0){
|
||||
/* seed the state, these constants would look nicer big-endian */
|
||||
s->state[0] = 0x67452301;
|
||||
s->state[1] = 0xefcdab89;
|
||||
s->state[2] = 0x98badcfe;
|
||||
s->state[3] = 0x10325476;
|
||||
s->seeded = 1;
|
||||
}
|
||||
|
||||
/* fill out the partial 64 byte block from previous calls */
|
||||
if(s->blen){
|
||||
i = 64 - s->blen;
|
||||
if(len < i)
|
||||
i = len;
|
||||
memmove(s->buf + s->blen, p, i);
|
||||
len -= i;
|
||||
s->blen += i;
|
||||
p += i;
|
||||
if(s->blen == 64){
|
||||
md4block(s->buf, s->blen, s);
|
||||
s->blen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* do 64 byte blocks */
|
||||
i = len & ~0x3f;
|
||||
if(i){
|
||||
md4block(p, i, s);
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
/* save the left overs if not last call */
|
||||
if(digest == 0){
|
||||
if(len){
|
||||
memmove(s->buf, p, len);
|
||||
s->blen += len;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* this is the last time through, pad what's left with 0x80,
|
||||
* 0's, and the input count to create a multiple of 64 bytes
|
||||
*/
|
||||
if(s->blen){
|
||||
p = s->buf;
|
||||
len = s->blen;
|
||||
} else {
|
||||
memmove(buf, p, len);
|
||||
p = buf;
|
||||
}
|
||||
s->len += len;
|
||||
e = p + len;
|
||||
if(len < 56)
|
||||
i = 56 - len;
|
||||
else
|
||||
i = 120 - len;
|
||||
memset(e, 0, i);
|
||||
*e = 0x80;
|
||||
len += i;
|
||||
|
||||
/* append the count */
|
||||
x[0] = s->len<<3;
|
||||
x[1] = s->len>>29;
|
||||
encode(p+len, x, 8);
|
||||
|
||||
/* digest the last part */
|
||||
md4block(p, len+8, s);
|
||||
|
||||
/* return result and free state */
|
||||
encode(digest, s->state, MD4dlen);
|
||||
if(s->malloced == 1)
|
||||
free(s);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* encodes input (u32int) into output (uchar). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
encode(uchar *output, u32int *input, ulong len)
|
||||
{
|
||||
u32int x;
|
||||
uchar *e;
|
||||
|
||||
for(e = output + len; output < e;) {
|
||||
x = *input++;
|
||||
*output++ = x;
|
||||
*output++ = x >> 8;
|
||||
*output++ = x >> 16;
|
||||
*output++ = x >> 24;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* decodes input (uchar) into output (u32int). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
decode(u32int *output, uchar *input, ulong len)
|
||||
{
|
||||
uchar *e;
|
||||
|
||||
for(e = input+len; input < e; input += 4)
|
||||
*output++ = input[0] | (input[1] << 8) |
|
||||
(input[2] << 16) | (input[3] << 24);
|
||||
}
|
31
libsec/md4test.c
Normal file
31
libsec/md4test.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
char *tests[] = {
|
||||
"",
|
||||
"a",
|
||||
"abc",
|
||||
"message digest",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
char **pp;
|
||||
uchar *p;
|
||||
int i;
|
||||
uchar digest[MD5dlen];
|
||||
|
||||
for(pp = tests; *pp; pp++){
|
||||
p = (uchar*)*pp;
|
||||
md4(p, strlen(*pp), digest, 0);
|
||||
for(i = 0; i < MD5dlen; i++)
|
||||
print("%2.2ux", digest[i]);
|
||||
print("\n");
|
||||
}
|
||||
}
|
148
libsec/md5.c
Normal file
148
libsec/md5.c
Normal file
@ -0,0 +1,148 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* rfc1321 requires that I include this. The code is new. The constants
|
||||
* all come from the rfc (hence the copyright). We trade a table for the
|
||||
* macros in rfc. The total size is a lot less. -- presotto
|
||||
*
|
||||
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
* rights reserved.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software forany particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
static void encode(uchar*, u32int*, ulong);
|
||||
static void decode(u32int*, uchar*, ulong);
|
||||
|
||||
extern void _md5block(uchar*, ulong, u32int*);
|
||||
|
||||
MD5state*
|
||||
md5(uchar *p, ulong len, uchar *digest, MD5state *s)
|
||||
{
|
||||
u32int x[16];
|
||||
uchar buf[128];
|
||||
int i;
|
||||
uchar *e;
|
||||
|
||||
if(s == nil){
|
||||
s = malloc(sizeof(*s));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->malloced = 1;
|
||||
}
|
||||
|
||||
if(s->seeded == 0){
|
||||
/* seed the state, these constants would look nicer big-endian */
|
||||
s->state[0] = 0x67452301;
|
||||
s->state[1] = 0xefcdab89;
|
||||
s->state[2] = 0x98badcfe;
|
||||
s->state[3] = 0x10325476;
|
||||
s->seeded = 1;
|
||||
}
|
||||
|
||||
/* fill out the partial 64 byte block from previous calls */
|
||||
if(s->blen){
|
||||
i = 64 - s->blen;
|
||||
if(len < i)
|
||||
i = len;
|
||||
memmove(s->buf + s->blen, p, i);
|
||||
len -= i;
|
||||
s->blen += i;
|
||||
p += i;
|
||||
if(s->blen == 64){
|
||||
_md5block(s->buf, s->blen, s->state);
|
||||
s->len += s->blen;
|
||||
s->blen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* do 64 byte blocks */
|
||||
i = len & ~0x3f;
|
||||
if(i){
|
||||
_md5block(p, i, s->state);
|
||||
s->len += i;
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
/* save the left overs if not last call */
|
||||
if(digest == 0){
|
||||
if(len){
|
||||
memmove(s->buf, p, len);
|
||||
s->blen += len;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* this is the last time through, pad what's left with 0x80,
|
||||
* 0's, and the input count to create a multiple of 64 bytes
|
||||
*/
|
||||
if(s->blen){
|
||||
p = s->buf;
|
||||
len = s->blen;
|
||||
} else {
|
||||
memmove(buf, p, len);
|
||||
p = buf;
|
||||
}
|
||||
s->len += len;
|
||||
e = p + len;
|
||||
if(len < 56)
|
||||
i = 56 - len;
|
||||
else
|
||||
i = 120 - len;
|
||||
memset(e, 0, i);
|
||||
*e = 0x80;
|
||||
len += i;
|
||||
|
||||
/* append the count */
|
||||
x[0] = s->len<<3;
|
||||
x[1] = s->len>>29;
|
||||
encode(p+len, x, 8);
|
||||
|
||||
/* digest the last part */
|
||||
_md5block(p, len+8, s->state);
|
||||
s->len += len;
|
||||
|
||||
/* return result and free state */
|
||||
encode(digest, s->state, MD5dlen);
|
||||
if(s->malloced == 1)
|
||||
free(s);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* encodes input (u32int) into output (uchar). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
encode(uchar *output, u32int *input, ulong len)
|
||||
{
|
||||
u32int x;
|
||||
uchar *e;
|
||||
|
||||
for(e = output + len; output < e;) {
|
||||
x = *input++;
|
||||
*output++ = x;
|
||||
*output++ = x >> 8;
|
||||
*output++ = x >> 16;
|
||||
*output++ = x >> 24;
|
||||
}
|
||||
}
|
267
libsec/md5block.c
Normal file
267
libsec/md5block.c
Normal file
@ -0,0 +1,267 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
/*
|
||||
* rfc1321 requires that I include this. The code is new. The constants
|
||||
* all come from the rfc (hence the copyright). We trade a table for the
|
||||
* macros in rfc. The total size is a lot less. -- presotto
|
||||
*
|
||||
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
* rights reserved.
|
||||
*
|
||||
* License to copy and use this software is granted provided that it
|
||||
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
* Algorithm" in all material mentioning or referencing this software
|
||||
* or this function.
|
||||
*
|
||||
* License is also granted to make and use derivative works provided
|
||||
* that such works are identified as "derived from the RSA Data
|
||||
* Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
* mentioning or referencing the derived work.
|
||||
*
|
||||
* RSA Data Security, Inc. makes no representations concerning either
|
||||
* the merchantability of this software or the suitability of this
|
||||
* software forany particular purpose. It is provided "as is"
|
||||
* without express or implied warranty of any kind.
|
||||
* These notices must be retained in any copies of any part of this
|
||||
* documentation and/or software.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Rotate ammounts used in the algorithm
|
||||
*/
|
||||
enum
|
||||
{
|
||||
S11= 7,
|
||||
S12= 12,
|
||||
S13= 17,
|
||||
S14= 22,
|
||||
|
||||
S21= 5,
|
||||
S22= 9,
|
||||
S23= 14,
|
||||
S24= 20,
|
||||
|
||||
S31= 4,
|
||||
S32= 11,
|
||||
S33= 16,
|
||||
S34= 23,
|
||||
|
||||
S41= 6,
|
||||
S42= 10,
|
||||
S43= 15,
|
||||
S44= 21,
|
||||
};
|
||||
|
||||
static u32int md5tab[] =
|
||||
{
|
||||
/* round 1 */
|
||||
/*[0]*/ 0xd76aa478,
|
||||
0xe8c7b756,
|
||||
0x242070db,
|
||||
0xc1bdceee,
|
||||
0xf57c0faf,
|
||||
0x4787c62a,
|
||||
0xa8304613,
|
||||
0xfd469501,
|
||||
0x698098d8,
|
||||
0x8b44f7af,
|
||||
0xffff5bb1,
|
||||
0x895cd7be,
|
||||
0x6b901122,
|
||||
0xfd987193,
|
||||
0xa679438e,
|
||||
0x49b40821,
|
||||
|
||||
/* round 2 */
|
||||
/*[16]*/0xf61e2562,
|
||||
0xc040b340,
|
||||
0x265e5a51,
|
||||
0xe9b6c7aa,
|
||||
0xd62f105d,
|
||||
0x2441453,
|
||||
0xd8a1e681,
|
||||
0xe7d3fbc8,
|
||||
0x21e1cde6,
|
||||
0xc33707d6,
|
||||
0xf4d50d87,
|
||||
0x455a14ed,
|
||||
0xa9e3e905,
|
||||
0xfcefa3f8,
|
||||
0x676f02d9,
|
||||
0x8d2a4c8a,
|
||||
|
||||
/* round 3 */
|
||||
/*[32]*/0xfffa3942,
|
||||
0x8771f681,
|
||||
0x6d9d6122,
|
||||
0xfde5380c,
|
||||
0xa4beea44,
|
||||
0x4bdecfa9,
|
||||
0xf6bb4b60,
|
||||
0xbebfbc70,
|
||||
0x289b7ec6,
|
||||
0xeaa127fa,
|
||||
0xd4ef3085,
|
||||
0x4881d05,
|
||||
0xd9d4d039,
|
||||
0xe6db99e5,
|
||||
0x1fa27cf8,
|
||||
0xc4ac5665,
|
||||
|
||||
/* round 4 */
|
||||
/*[48]*/0xf4292244,
|
||||
0x432aff97,
|
||||
0xab9423a7,
|
||||
0xfc93a039,
|
||||
0x655b59c3,
|
||||
0x8f0ccc92,
|
||||
0xffeff47d,
|
||||
0x85845dd1,
|
||||
0x6fa87e4f,
|
||||
0xfe2ce6e0,
|
||||
0xa3014314,
|
||||
0x4e0811a1,
|
||||
0xf7537e82,
|
||||
0xbd3af235,
|
||||
0x2ad7d2bb,
|
||||
0xeb86d391,
|
||||
};
|
||||
|
||||
static void decode(u32int*, uchar*, ulong);
|
||||
extern void _md5block(uchar *p, ulong len, u32int *s);
|
||||
|
||||
void
|
||||
_md5block(uchar *p, ulong len, u32int *s)
|
||||
{
|
||||
u32int a, b, c, d, sh;
|
||||
u32int *t;
|
||||
uchar *end;
|
||||
u32int x[16];
|
||||
|
||||
for(end = p+len; p < end; p += 64){
|
||||
a = s[0];
|
||||
b = s[1];
|
||||
c = s[2];
|
||||
d = s[3];
|
||||
|
||||
decode(x, p, 64);
|
||||
|
||||
t = md5tab;
|
||||
sh = 0;
|
||||
for(; sh != 16; t += 4){
|
||||
a += ((c ^ d) & b) ^ d;
|
||||
a += x[sh] + t[0];
|
||||
a = (a << S11) | (a >> (32 - S11));
|
||||
a += b;
|
||||
|
||||
d += ((b ^ c) & a) ^ c;
|
||||
d += x[sh + 1] + t[1];
|
||||
d = (d << S12) | (d >> (32 - S12));
|
||||
d += a;
|
||||
|
||||
c += ((a ^ b) & d) ^ b;
|
||||
c += x[sh + 2] + t[2];
|
||||
c = (c << S13) | (c >> (32 - S13));
|
||||
c += d;
|
||||
|
||||
b += ((d ^ a) & c) ^ a;
|
||||
b += x[sh + 3] + t[3];
|
||||
b = (b << S14) | (b >> (32 - S14));
|
||||
b += c;
|
||||
|
||||
sh += 4;
|
||||
}
|
||||
sh = 1;
|
||||
for(; sh != 1+20*4; t += 4){
|
||||
a += ((b ^ c) & d) ^ c;
|
||||
a += x[sh & 0xf] + t[0];
|
||||
a = (a << S21) | (a >> (32 - S21));
|
||||
a += b;
|
||||
|
||||
d += ((a ^ b) & c) ^ b;
|
||||
d += x[(sh + 5) & 0xf] + t[1];
|
||||
d = (d << S22) | (d >> (32 - S22));
|
||||
d += a;
|
||||
|
||||
c += ((d ^ a) & b) ^ a;
|
||||
c += x[(sh + 10) & 0xf] + t[2];
|
||||
c = (c << S23) | (c >> (32 - S23));
|
||||
c += d;
|
||||
|
||||
b += ((c ^ d) & a) ^ d;
|
||||
b += x[(sh + 15) & 0xf] + t[3];
|
||||
b = (b << S24) | (b >> (32 - S24));
|
||||
b += c;
|
||||
|
||||
sh += 20;
|
||||
}
|
||||
sh = 5;
|
||||
for(; sh != 5+12*4; t += 4){
|
||||
a += b ^ c ^ d;
|
||||
a += x[sh & 0xf] + t[0];
|
||||
a = (a << S31) | (a >> (32 - S31));
|
||||
a += b;
|
||||
|
||||
d += a ^ b ^ c;
|
||||
d += x[(sh + 3) & 0xf] + t[1];
|
||||
d = (d << S32) | (d >> (32 - S32));
|
||||
d += a;
|
||||
|
||||
c += d ^ a ^ b;
|
||||
c += x[(sh + 6) & 0xf] + t[2];
|
||||
c = (c << S33) | (c >> (32 - S33));
|
||||
c += d;
|
||||
|
||||
b += c ^ d ^ a;
|
||||
b += x[(sh + 9) & 0xf] + t[3];
|
||||
b = (b << S34) | (b >> (32 - S34));
|
||||
b += c;
|
||||
|
||||
sh += 12;
|
||||
}
|
||||
sh = 0;
|
||||
for(; sh != 28*4; t += 4){
|
||||
a += c ^ (b | ~d);
|
||||
a += x[sh & 0xf] + t[0];
|
||||
a = (a << S41) | (a >> (32 - S41));
|
||||
a += b;
|
||||
|
||||
d += b ^ (a | ~c);
|
||||
d += x[(sh + 7) & 0xf] + t[1];
|
||||
d = (d << S42) | (d >> (32 - S42));
|
||||
d += a;
|
||||
|
||||
c += a ^ (d | ~b);
|
||||
c += x[(sh + 14) & 0xf] + t[2];
|
||||
c = (c << S43) | (c >> (32 - S43));
|
||||
c += d;
|
||||
|
||||
b += d ^ (c | ~a);
|
||||
b += x[(sh + 21) & 0xf] + t[3];
|
||||
b = (b << S44) | (b >> (32 - S44));
|
||||
b += c;
|
||||
|
||||
sh += 28;
|
||||
}
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* decodes input (uchar) into output (u32int). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
decode(u32int *output, uchar *input, ulong len)
|
||||
{
|
||||
uchar *e;
|
||||
|
||||
for(e = input+len; input < e; input += 4)
|
||||
*output++ = input[0] | (input[1] << 8) |
|
||||
(input[2] << 16) | (input[3] << 24);
|
||||
}
|
37
libsec/md5pickle.c
Normal file
37
libsec/md5pickle.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
char*
|
||||
md5pickle(MD5state *s)
|
||||
{
|
||||
char *p;
|
||||
int m, n;
|
||||
|
||||
m = 4*9+4*((s->blen+3)/3);
|
||||
p = malloc(m);
|
||||
if(p == nil)
|
||||
return p;
|
||||
n = sprint(p, "%8.8ux %8.8ux %8.8ux %8.8ux ",
|
||||
s->state[0], s->state[1], s->state[2],
|
||||
s->state[3]);
|
||||
enc64(p+n, m-n, s->buf, s->blen);
|
||||
return p;
|
||||
}
|
||||
|
||||
MD5state*
|
||||
md5unpickle(char *p)
|
||||
{
|
||||
MD5state *s;
|
||||
|
||||
s = malloc(sizeof(*s));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
s->state[0] = strtoul(p, &p, 16);
|
||||
s->state[1] = strtoul(p, &p, 16);
|
||||
s->state[2] = strtoul(p, &p, 16);
|
||||
s->state[3] = strtoul(p, &p, 16);
|
||||
s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p));
|
||||
s->malloced = 1;
|
||||
s->seeded = 1;
|
||||
return s;
|
||||
}
|
55
libsec/mkfile
Normal file
55
libsec/mkfile
Normal file
@ -0,0 +1,55 @@
|
||||
<$DSRC/mkfile-$CONF
|
||||
TARG=libsec.$L
|
||||
|
||||
OFILES=\
|
||||
aes.$O\
|
||||
blowfish.$O\
|
||||
decodepem.$O\
|
||||
des.$O\
|
||||
des3CBC.$O\
|
||||
des3ECB.$O\
|
||||
desCBC.$O\
|
||||
desECB.$O\
|
||||
desmodes.$O\
|
||||
dsaalloc.$O\
|
||||
dsagen.$O\
|
||||
dsaprimes.$O\
|
||||
dsaprivtopub.$O\
|
||||
dsasign.$O\
|
||||
dsaverify.$O\
|
||||
egalloc.$O\
|
||||
egdecrypt.$O\
|
||||
egencrypt.$O\
|
||||
eggen.$O\
|
||||
egprivtopub.$O\
|
||||
egsign.$O\
|
||||
egverify.$O\
|
||||
fastrand.$O\
|
||||
genprime.$O\
|
||||
genrandom.$O\
|
||||
gensafeprime.$O\
|
||||
genstrongprime.$O\
|
||||
hmac.$O\
|
||||
md4.$O\
|
||||
md5.$O\
|
||||
md5block.$O\
|
||||
md5pickle.$O\
|
||||
nfastrand.$O\
|
||||
prng.$O\
|
||||
probably_prime.$O\
|
||||
rc4.$O\
|
||||
rsaalloc.$O\
|
||||
rsadecrypt.$O\
|
||||
rsaencrypt.$O\
|
||||
rsafill.$O\
|
||||
rsagen.$O\
|
||||
rsaprivtopub.$O\
|
||||
sha1.$O\
|
||||
sha1block.$O\
|
||||
sha1pickle.$O\
|
||||
smallprimes.$O
|
||||
|
||||
HFILE=\
|
||||
os.h
|
||||
|
||||
<$DSRC/mklib-$CONF
|
23
libsec/nfastrand.c
Normal file
23
libsec/nfastrand.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <libsec.h>
|
||||
|
||||
#define Maxrand ((1UL<<31)-1)
|
||||
|
||||
ulong
|
||||
nfastrand(ulong n)
|
||||
{
|
||||
ulong m, r;
|
||||
|
||||
/*
|
||||
* set m to the maximum multiple of n <= 2^31-1
|
||||
* so we want a random number < m.
|
||||
*/
|
||||
if(n > Maxrand)
|
||||
abort();
|
||||
|
||||
m = Maxrand - Maxrand % n;
|
||||
while((r = fastrand()) >= m)
|
||||
;
|
||||
return r%n;
|
||||
}
|
2
libsec/os.h
Normal file
2
libsec/os.h
Normal file
@ -0,0 +1,2 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
41
libsec/primetest.c
Normal file
41
libsec/primetest.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
mpint *z = mpnew(0);
|
||||
mpint *p = mpnew(0);
|
||||
mpint *q = mpnew(0);
|
||||
mpint *nine = mpnew(0);
|
||||
|
||||
fmtinstall('B', mpconv);
|
||||
strtomp("2492491", nil, 16, z); // 38347921 = x*y = (2**28-9)/7,
|
||||
// an example of 3**(n-1)=1 mod n
|
||||
strtomp("15662C00E811", nil, 16, p);// 23528569104401, a prime
|
||||
uitomp(9, nine);
|
||||
|
||||
if(probably_prime(z, 5) == 1)
|
||||
fprint(2, "tricked primality test\n");
|
||||
if(probably_prime(nine, 5) == 1)
|
||||
fprint(2, "9 passed primality test!\n");
|
||||
if(probably_prime(p, 25) == 1)
|
||||
fprint(2, "ok\n");
|
||||
|
||||
DSAprimes(q, p, nil);
|
||||
print("q=%B\np=%B\n", q, p);
|
||||
|
||||
exits(0);
|
||||
}
|
||||
|
||||
// example output, checked with Maple:
|
||||
// seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E
|
||||
// q=E0F0EF284E10796C5A2A511E94748BA03C795C13
|
||||
// = 1284186945063585093695748280224501481698995297299
|
||||
// p=C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBBDB12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A863A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D93D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D
|
||||
// = 137715385439333164327584575331308277462546592976152006175830654712456008630139443747529133857837818585400418619916530061955288983751958831927807888408309879880101870216437711393638413509484569804814373511469405934988856674935304074081350525593807908358867354528898618574659752879015380013845760006721861915693
|
||||
// r=DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241CEF2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E887D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D21C4656848614D888A4
|
||||
// = 107239359478548771267308764204625458348785444483302647285245969203446101233421655396874997253111222983406676955642093641709149748793954493558324738441197139556917622937892491175016280660608595599724194374948056515856812347094848443460715881455884639869144172708
|
||||
// g=2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D2327173444ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD410E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734E3E2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1
|
||||
// = 33081848392740465806285326014906437543653045153885419334085917570615301913274531387168723847139029827598735376746057461417880810924280288611116213062512408829164220104555543445909528701551198146080221790002337033997295756585193926863581671466708482411159477816144226847280417522524922667065714073338662508017
|
15
libsec/prng.c
Normal file
15
libsec/prng.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
//
|
||||
// just use the libc prng to fill a buffer
|
||||
//
|
||||
void
|
||||
prng(uchar *p, int n)
|
||||
{
|
||||
uchar *e;
|
||||
|
||||
for(e = p+n; p < e; p++)
|
||||
*p = rand();
|
||||
}
|
84
libsec/probably_prime.c
Normal file
84
libsec/probably_prime.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// Miller-Rabin probabilistic primality testing
|
||||
// Knuth (1981) Seminumerical Algorithms, p.379
|
||||
// Menezes et al () Handbook, p.39
|
||||
// 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
|
||||
int
|
||||
probably_prime(mpint *n, int nrep)
|
||||
{
|
||||
int j, k, rep, nbits, isprime = 1;
|
||||
mpint *nm1, *q, *x, *y, *r;
|
||||
|
||||
if(n->sign < 0)
|
||||
sysfatal("negative prime candidate");
|
||||
|
||||
if(nrep <= 0)
|
||||
nrep = 18;
|
||||
|
||||
k = mptoi(n);
|
||||
if(k == 2) // 2 is prime
|
||||
return 1;
|
||||
if(k < 2) // 1 is not prime
|
||||
return 0;
|
||||
if((n->p[0] & 1) == 0) // even is not prime
|
||||
return 0;
|
||||
|
||||
// test against small prime numbers
|
||||
if(smallprimetest(n) < 0)
|
||||
return 0;
|
||||
|
||||
// fermat test, 2^n mod n == 2 if p is prime
|
||||
x = uitomp(2, nil);
|
||||
y = mpnew(0);
|
||||
mpexp(x, n, n, y);
|
||||
k = mptoi(y);
|
||||
if(k != 2){
|
||||
mpfree(x);
|
||||
mpfree(y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nbits = mpsignif(n);
|
||||
nm1 = mpnew(nbits);
|
||||
mpsub(n, mpone, nm1); // nm1 = n - 1 */
|
||||
k = mplowbits0(nm1);
|
||||
q = mpnew(0);
|
||||
mpright(nm1, k, q); // q = (n-1)/2**k
|
||||
|
||||
for(rep = 0; rep < nrep; rep++){
|
||||
|
||||
// x = random in [2, n-2]
|
||||
r = mprand(nbits, prng, nil);
|
||||
mpmod(r, nm1, x);
|
||||
mpfree(r);
|
||||
if(mpcmp(x, mpone) <= 0)
|
||||
continue;
|
||||
|
||||
// y = x**q mod n
|
||||
mpexp(x, q, n, y);
|
||||
|
||||
if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
|
||||
goto done;
|
||||
|
||||
for(j = 1; j < k; j++){
|
||||
mpmul(y, y, x);
|
||||
mpmod(x, n, y); // y = y*y mod n
|
||||
if(mpcmp(y, nm1) == 0)
|
||||
goto done;
|
||||
if(mpcmp(y, mpone) == 0){
|
||||
isprime = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
isprime = 0;
|
||||
}
|
||||
done:
|
||||
mpfree(y);
|
||||
mpfree(x);
|
||||
mpfree(q);
|
||||
mpfree(nm1);
|
||||
return isprime;
|
||||
}
|
BIN
libsec/ranlib.core
Normal file
BIN
libsec/ranlib.core
Normal file
Binary file not shown.
104
libsec/rc4.c
Normal file
104
libsec/rc4.c
Normal file
@ -0,0 +1,104 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
void
|
||||
setupRC4state(RC4state *key, uchar *start, int n)
|
||||
{
|
||||
int t;
|
||||
int index2;
|
||||
uchar *state;
|
||||
uchar *p, *e, *sp, *se;
|
||||
|
||||
state = key->state;
|
||||
se = &state[256];
|
||||
for(sp = state; sp < se; sp++)
|
||||
*sp = sp - state;
|
||||
|
||||
key->x = 0;
|
||||
key->y = 0;
|
||||
index2 = 0;
|
||||
e = start + n;
|
||||
p = start;
|
||||
for(sp = state; sp < se; sp++)
|
||||
{
|
||||
t = *sp;
|
||||
index2 = (*p + t + index2) & 255;
|
||||
*sp = state[index2];
|
||||
state[index2] = t;
|
||||
if(++p >= e)
|
||||
p = start;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rc4(RC4state *key, uchar *p, int len)
|
||||
{
|
||||
int tx, ty;
|
||||
int x, y;
|
||||
uchar *state;
|
||||
uchar *e;
|
||||
|
||||
x = key->x;
|
||||
y = key->y;
|
||||
state = &key->state[0];
|
||||
for(e = p + len; p < e; p++)
|
||||
{
|
||||
x = (x+1)&255;
|
||||
tx = state[x];
|
||||
y = (y+tx)&255;
|
||||
ty = state[y];
|
||||
state[x] = ty;
|
||||
state[y] = tx;
|
||||
*p ^= state[(tx+ty)&255];
|
||||
}
|
||||
key->x = x;
|
||||
key->y = y;
|
||||
}
|
||||
|
||||
void
|
||||
rc4skip(RC4state *key, int len)
|
||||
{
|
||||
int tx, ty;
|
||||
int x, y;
|
||||
uchar *state;
|
||||
int i;
|
||||
|
||||
x = key->x;
|
||||
y = key->y;
|
||||
state = &key->state[0];
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
x = (x+1)&255;
|
||||
tx = state[x];
|
||||
y = (y+tx)&255;
|
||||
ty = state[y];
|
||||
state[x] = ty;
|
||||
state[y] = tx;
|
||||
}
|
||||
key->x = x;
|
||||
key->y = y;
|
||||
}
|
||||
|
||||
void
|
||||
rc4back(RC4state *key, int len)
|
||||
{
|
||||
int tx, ty;
|
||||
int x, y;
|
||||
uchar *state;
|
||||
int i;
|
||||
|
||||
x = key->x;
|
||||
y = key->y;
|
||||
state = &key->state[0];
|
||||
for(i=0; i<len; i++)
|
||||
{
|
||||
ty = state[x];
|
||||
tx = state[y];
|
||||
state[y] = ty;
|
||||
state[x] = tx;
|
||||
y = (y-tx)&255;
|
||||
x = (x-1)&255;
|
||||
}
|
||||
key->x = x;
|
||||
key->y = y;
|
||||
}
|
50
libsec/readcert.c
Normal file
50
libsec/readcert.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
static char*
|
||||
readfile(char *name)
|
||||
{
|
||||
int fd;
|
||||
char *s;
|
||||
Dir *d;
|
||||
|
||||
fd = open(name, OREAD);
|
||||
if(fd < 0)
|
||||
return nil;
|
||||
if((d = dirfstat(fd)) == nil)
|
||||
return nil;
|
||||
s = malloc(d->length + 1);
|
||||
if(s == nil || readn(fd, s, d->length) != d->length){
|
||||
free(s);
|
||||
free(d);
|
||||
close(fd);
|
||||
return nil;
|
||||
}
|
||||
close(fd);
|
||||
s[d->length] = '\0';
|
||||
free(d);
|
||||
return s;
|
||||
}
|
||||
|
||||
uchar*
|
||||
readcert(char *filename, int *pcertlen)
|
||||
{
|
||||
char *pem;
|
||||
uchar *binary;
|
||||
|
||||
pem = readfile(filename);
|
||||
if(pem == nil){
|
||||
werrstr("can't read %s", filename);
|
||||
return nil;
|
||||
}
|
||||
binary = decodepem(pem, "CERTIFICATE", pcertlen);
|
||||
free(pem);
|
||||
if(binary == nil){
|
||||
werrstr("can't parse %s", filename);
|
||||
return nil;
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
52
libsec/rsaalloc.c
Normal file
52
libsec/rsaalloc.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
RSApub*
|
||||
rsapuballoc(void)
|
||||
{
|
||||
RSApub *rsa;
|
||||
|
||||
rsa = mallocz(sizeof(*rsa), 1);
|
||||
if(rsa == nil)
|
||||
sysfatal("rsapuballoc");
|
||||
return rsa;
|
||||
}
|
||||
|
||||
void
|
||||
rsapubfree(RSApub *rsa)
|
||||
{
|
||||
if(rsa == nil)
|
||||
return;
|
||||
mpfree(rsa->ek);
|
||||
mpfree(rsa->n);
|
||||
free(rsa);
|
||||
}
|
||||
|
||||
|
||||
RSApriv*
|
||||
rsaprivalloc(void)
|
||||
{
|
||||
RSApriv *rsa;
|
||||
|
||||
rsa = mallocz(sizeof(*rsa), 1);
|
||||
if(rsa == nil)
|
||||
sysfatal("rsaprivalloc");
|
||||
return rsa;
|
||||
}
|
||||
|
||||
void
|
||||
rsaprivfree(RSApriv *rsa)
|
||||
{
|
||||
if(rsa == nil)
|
||||
return;
|
||||
mpfree(rsa->pub.ek);
|
||||
mpfree(rsa->pub.n);
|
||||
mpfree(rsa->dk);
|
||||
mpfree(rsa->p);
|
||||
mpfree(rsa->q);
|
||||
mpfree(rsa->kp);
|
||||
mpfree(rsa->kq);
|
||||
mpfree(rsa->c2);
|
||||
free(rsa);
|
||||
}
|
37
libsec/rsadecrypt.c
Normal file
37
libsec/rsadecrypt.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
// decrypt rsa using garner's algorithm for the chinese remainder theorem
|
||||
// seminumerical algorithms, knuth, pp 253-254
|
||||
// applied cryptography, menezes et al, pg 612
|
||||
mpint*
|
||||
rsadecrypt(RSApriv *rsa, mpint *in, mpint *out)
|
||||
{
|
||||
mpint *v1, *v2;
|
||||
|
||||
if(out == nil)
|
||||
out = mpnew(0);
|
||||
|
||||
// convert in to modular representation
|
||||
v1 = mpnew(0);
|
||||
mpmod(in, rsa->p, v1);
|
||||
v2 = mpnew(0);
|
||||
mpmod(in, rsa->q, v2);
|
||||
|
||||
// exponentiate the modular rep
|
||||
mpexp(v1, rsa->kp, rsa->p, v1);
|
||||
mpexp(v2, rsa->kq, rsa->q, v2);
|
||||
|
||||
// out = v1 + p*((v2-v1)*c2 mod q)
|
||||
mpsub(v2, v1, v2);
|
||||
mpmul(v2, rsa->c2, v2);
|
||||
mpmod(v2, rsa->q, v2);
|
||||
mpmul(v2, rsa->p, out);
|
||||
mpadd(v1, out, out);
|
||||
|
||||
mpfree(v1);
|
||||
mpfree(v2);
|
||||
|
||||
return out;
|
||||
}
|
12
libsec/rsaencrypt.c
Normal file
12
libsec/rsaencrypt.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
mpint*
|
||||
rsaencrypt(RSApub *rsa, mpint *in, mpint *out)
|
||||
{
|
||||
if(out == nil)
|
||||
out = mpnew(0);
|
||||
mpexp(in, rsa->ek, rsa->n, out);
|
||||
return out;
|
||||
}
|
61
libsec/rsafill.c
Normal file
61
libsec/rsafill.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
RSApriv*
|
||||
rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
|
||||
{
|
||||
mpint *c2, *kq, *kp, *x;
|
||||
RSApriv *rsa;
|
||||
|
||||
// make sure we're not being hoodwinked
|
||||
if(!probably_prime(p, 10) || !probably_prime(q, 10)){
|
||||
werrstr("rsafill: p or q not prime");
|
||||
return nil;
|
||||
}
|
||||
x = mpnew(0);
|
||||
mpmul(p, q, x);
|
||||
if(mpcmp(n, x) != 0){
|
||||
werrstr("rsafill: n != p*q");
|
||||
mpfree(x);
|
||||
return nil;
|
||||
}
|
||||
c2 = mpnew(0);
|
||||
mpsub(p, mpone, c2);
|
||||
mpsub(q, mpone, x);
|
||||
mpmul(c2, x, x);
|
||||
mpmul(e, d, c2);
|
||||
mpmod(c2, x, x);
|
||||
if(mpcmp(x, mpone) != 0){
|
||||
werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)");
|
||||
mpfree(x);
|
||||
mpfree(c2);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// compute chinese remainder coefficient
|
||||
mpinvert(p, q, c2);
|
||||
|
||||
// for crt a**k mod p == (a**(k mod p-1)) mod p
|
||||
kq = mpnew(0);
|
||||
kp = mpnew(0);
|
||||
mpsub(p, mpone, x);
|
||||
mpmod(d, x, kp);
|
||||
mpsub(q, mpone, x);
|
||||
mpmod(d, x, kq);
|
||||
|
||||
rsa = rsaprivalloc();
|
||||
rsa->pub.ek = mpcopy(e);
|
||||
rsa->pub.n = mpcopy(n);
|
||||
rsa->dk = mpcopy(d);
|
||||
rsa->kp = kp;
|
||||
rsa->kq = kq;
|
||||
rsa->p = mpcopy(p);
|
||||
rsa->q = mpcopy(q);
|
||||
rsa->c2 = c2;
|
||||
|
||||
mpfree(x);
|
||||
|
||||
return rsa;
|
||||
}
|
||||
|
82
libsec/rsagen.c
Normal file
82
libsec/rsagen.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
static void
|
||||
genrand(mpint *p, int n)
|
||||
{
|
||||
mpdigit x;
|
||||
|
||||
// generate n random bits with high set
|
||||
mpbits(p, n);
|
||||
genrandom((uchar*)p->p, (n+7)/8);
|
||||
p->top = (n+Dbits-1)/Dbits;
|
||||
x = 1;
|
||||
x <<= ((n-1)%Dbits);
|
||||
p->p[p->top-1] &= (x-1);
|
||||
p->p[p->top-1] |= x;
|
||||
}
|
||||
|
||||
RSApriv*
|
||||
rsagen(int nlen, int elen, int rounds)
|
||||
{
|
||||
mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
|
||||
RSApriv *rsa;
|
||||
|
||||
p = mpnew(nlen/2);
|
||||
q = mpnew(nlen/2);
|
||||
n = mpnew(nlen);
|
||||
e = mpnew(elen);
|
||||
d = mpnew(0);
|
||||
phi = mpnew(nlen);
|
||||
|
||||
// create the prime factors and euclid's function
|
||||
genstrongprime(p, nlen/2, rounds);
|
||||
genstrongprime(q, nlen - mpsignif(p) + 1, rounds);
|
||||
mpmul(p, q, n);
|
||||
mpsub(p, mpone, e);
|
||||
mpsub(q, mpone, d);
|
||||
mpmul(e, d, phi);
|
||||
|
||||
// find an e relatively prime to phi
|
||||
t1 = mpnew(0);
|
||||
t2 = mpnew(0);
|
||||
genrand(e, elen);
|
||||
for(;;){
|
||||
mpextendedgcd(e, phi, d, t1, t2);
|
||||
if(mpcmp(d, mpone) == 0)
|
||||
break;
|
||||
mpadd(mpone, e, e);
|
||||
}
|
||||
mpfree(t1);
|
||||
mpfree(t2);
|
||||
|
||||
// d = e**-1 mod phi
|
||||
mpinvert(e, phi, d);
|
||||
|
||||
// compute chinese remainder coefficient
|
||||
c2 = mpnew(0);
|
||||
mpinvert(p, q, c2);
|
||||
|
||||
// for crt a**k mod p == (a**(k mod p-1)) mod p
|
||||
kq = mpnew(0);
|
||||
kp = mpnew(0);
|
||||
mpsub(p, mpone, phi);
|
||||
mpmod(d, phi, kp);
|
||||
mpsub(q, mpone, phi);
|
||||
mpmod(d, phi, kq);
|
||||
|
||||
rsa = rsaprivalloc();
|
||||
rsa->pub.ek = e;
|
||||
rsa->pub.n = n;
|
||||
rsa->dk = d;
|
||||
rsa->kp = kp;
|
||||
rsa->kq = kq;
|
||||
rsa->p = p;
|
||||
rsa->q = q;
|
||||
rsa->c2 = c2;
|
||||
|
||||
mpfree(phi);
|
||||
|
||||
return rsa;
|
||||
}
|
16
libsec/rsaprivtopub.c
Normal file
16
libsec/rsaprivtopub.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
RSApub*
|
||||
rsaprivtopub(RSApriv *priv)
|
||||
{
|
||||
RSApub *pub;
|
||||
|
||||
pub = rsapuballoc();
|
||||
if(pub == nil)
|
||||
return nil;
|
||||
pub->n = mpcopy(priv->pub.n);
|
||||
pub->ek = mpcopy(priv->pub.ek);
|
||||
return pub;
|
||||
}
|
57
libsec/rsatest.c
Normal file
57
libsec/rsatest.c
Normal file
@ -0,0 +1,57 @@
|
||||
#include "os.h"
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
#include <bio.h>
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
RSApriv *rsa;
|
||||
Biobuf b;
|
||||
char *p;
|
||||
int n;
|
||||
mpint *clr, *enc, *clr2;
|
||||
uchar buf[4096];
|
||||
uchar *e;
|
||||
vlong start;
|
||||
|
||||
fmtinstall('B', mpconv);
|
||||
|
||||
rsa = rsagen(1024, 16, 0);
|
||||
if(rsa == nil)
|
||||
sysfatal("rsagen");
|
||||
Binit(&b, 0, OREAD);
|
||||
clr = mpnew(0);
|
||||
clr2 = mpnew(0);
|
||||
enc = mpnew(0);
|
||||
|
||||
strtomp("123456789abcdef123456789abcdef123456789abcdef123456789abcdef", nil, 16, clr);
|
||||
rsaencrypt(&rsa->pub, clr, enc);
|
||||
|
||||
start = nsec();
|
||||
for(n = 0; n < 10; n++)
|
||||
rsadecrypt(rsa, enc, clr);
|
||||
print("%lld\n", nsec()-start);
|
||||
|
||||
start = nsec();
|
||||
for(n = 0; n < 10; n++)
|
||||
mpexp(enc, rsa->dk, rsa->pub.n, clr2);
|
||||
print("%lld\n", nsec()-start);
|
||||
|
||||
if(mpcmp(clr, clr2) != 0)
|
||||
print("%B != %B\n", clr, clr2);
|
||||
|
||||
print("> ");
|
||||
while(p = Brdline(&b, '\n')){
|
||||
n = Blinelen(&b);
|
||||
letomp((uchar*)p, n, clr);
|
||||
print("clr %B\n", clr);
|
||||
rsaencrypt(&rsa->pub, clr, enc);
|
||||
print("enc %B\n", enc);
|
||||
rsadecrypt(rsa, enc, clr);
|
||||
print("clr %B\n", clr);
|
||||
n = mptole(clr, buf, sizeof(buf), nil);
|
||||
write(1, buf, n);
|
||||
print("> ");
|
||||
}
|
||||
}
|
127
libsec/sha1.c
Normal file
127
libsec/sha1.c
Normal file
@ -0,0 +1,127 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
static void encode(uchar*, u32int*, ulong);
|
||||
|
||||
extern void _sha1block(uchar*, ulong, u32int*);
|
||||
|
||||
/*
|
||||
* we require len to be a multiple of 64 for all but
|
||||
* the last call. There must be room in the input buffer
|
||||
* to pad.
|
||||
*/
|
||||
SHA1state*
|
||||
sha1(uchar *p, ulong len, uchar *digest, SHA1state *s)
|
||||
{
|
||||
uchar buf[128];
|
||||
u32int x[16];
|
||||
int i;
|
||||
uchar *e;
|
||||
|
||||
if(s == nil){
|
||||
s = malloc(sizeof(*s));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->malloced = 1;
|
||||
}
|
||||
|
||||
if(s->seeded == 0){
|
||||
/* seed the state, these constants would look nicer big-endian */
|
||||
s->state[0] = 0x67452301;
|
||||
s->state[1] = 0xefcdab89;
|
||||
s->state[2] = 0x98badcfe;
|
||||
s->state[3] = 0x10325476;
|
||||
s->state[4] = 0xc3d2e1f0;
|
||||
s->seeded = 1;
|
||||
}
|
||||
|
||||
/* fill out the partial 64 byte block from previous calls */
|
||||
if(s->blen){
|
||||
i = 64 - s->blen;
|
||||
if(len < i)
|
||||
i = len;
|
||||
memmove(s->buf + s->blen, p, i);
|
||||
len -= i;
|
||||
s->blen += i;
|
||||
p += i;
|
||||
if(s->blen == 64){
|
||||
_sha1block(s->buf, s->blen, s->state);
|
||||
s->len += s->blen;
|
||||
s->blen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* do 64 byte blocks */
|
||||
i = len & ~0x3f;
|
||||
if(i){
|
||||
_sha1block(p, i, s->state);
|
||||
s->len += i;
|
||||
len -= i;
|
||||
p += i;
|
||||
}
|
||||
|
||||
/* save the left overs if not last call */
|
||||
if(digest == 0){
|
||||
if(len){
|
||||
memmove(s->buf, p, len);
|
||||
s->blen += len;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* this is the last time through, pad what's left with 0x80,
|
||||
* 0's, and the input count to create a multiple of 64 bytes
|
||||
*/
|
||||
if(s->blen){
|
||||
p = s->buf;
|
||||
len = s->blen;
|
||||
} else {
|
||||
memmove(buf, p, len);
|
||||
p = buf;
|
||||
}
|
||||
s->len += len;
|
||||
e = p + len;
|
||||
if(len < 56)
|
||||
i = 56 - len;
|
||||
else
|
||||
i = 120 - len;
|
||||
memset(e, 0, i);
|
||||
*e = 0x80;
|
||||
len += i;
|
||||
|
||||
/* append the count */
|
||||
x[0] = s->len>>29;
|
||||
x[1] = s->len<<3;
|
||||
encode(p+len, x, 8);
|
||||
|
||||
/* digest the last part */
|
||||
_sha1block(p, len+8, s->state);
|
||||
s->len += len+8;
|
||||
|
||||
/* return result and free state */
|
||||
encode(digest, s->state, SHA1dlen);
|
||||
if(s->malloced == 1)
|
||||
free(s);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/*
|
||||
* encodes input (ulong) into output (uchar). Assumes len is
|
||||
* a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
encode(uchar *output, u32int *input, ulong len)
|
||||
{
|
||||
u32int x;
|
||||
uchar *e;
|
||||
|
||||
for(e = output + len; output < e;) {
|
||||
x = *input++;
|
||||
*output++ = x >> 24;
|
||||
*output++ = x >> 16;
|
||||
*output++ = x >> 8;
|
||||
*output++ = x;
|
||||
}
|
||||
}
|
187
libsec/sha1block.c
Normal file
187
libsec/sha1block.c
Normal file
@ -0,0 +1,187 @@
|
||||
#include "os.h"
|
||||
|
||||
void
|
||||
_sha1block(uchar *p, ulong len, u32int *s)
|
||||
{
|
||||
u32int a, b, c, d, e, x;
|
||||
uchar *end;
|
||||
u32int *wp, *wend;
|
||||
u32int w[80];
|
||||
|
||||
/* at this point, we have a multiple of 64 bytes */
|
||||
for(end = p+len; p < end;){
|
||||
a = s[0];
|
||||
b = s[1];
|
||||
c = s[2];
|
||||
d = s[3];
|
||||
e = s[4];
|
||||
|
||||
wend = w + 15;
|
||||
for(wp = w; wp < wend; wp += 5){
|
||||
wp[0] = (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
||||
e += ((a<<5) | (a>>27)) + wp[0];
|
||||
e += 0x5a827999 + (((c^d)&b)^d);
|
||||
b = (b<<30)|(b>>2);
|
||||
|
||||
wp[1] = (p[4]<<24) | (p[5]<<16) | (p[6]<<8) | p[7];
|
||||
d += ((e<<5) | (e>>27)) + wp[1];
|
||||
d += 0x5a827999 + (((b^c)&a)^c);
|
||||
a = (a<<30)|(a>>2);
|
||||
|
||||
wp[2] = (p[8]<<24) | (p[9]<<16) | (p[10]<<8) | p[11];
|
||||
c += ((d<<5) | (d>>27)) + wp[2];
|
||||
c += 0x5a827999 + (((a^b)&e)^b);
|
||||
e = (e<<30)|(e>>2);
|
||||
|
||||
wp[3] = (p[12]<<24) | (p[13]<<16) | (p[14]<<8) | p[15];
|
||||
b += ((c<<5) | (c>>27)) + wp[3];
|
||||
b += 0x5a827999 + (((e^a)&d)^a);
|
||||
d = (d<<30)|(d>>2);
|
||||
|
||||
wp[4] = (p[16]<<24) | (p[17]<<16) | (p[18]<<8) | p[19];
|
||||
a += ((b<<5) | (b>>27)) + wp[4];
|
||||
a += 0x5a827999 + (((d^e)&c)^e);
|
||||
c = (c<<30)|(c>>2);
|
||||
|
||||
p += 20;
|
||||
}
|
||||
|
||||
wp[0] = (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
||||
e += ((a<<5) | (a>>27)) + wp[0];
|
||||
e += 0x5a827999 + (((c^d)&b)^d);
|
||||
b = (b<<30)|(b>>2);
|
||||
|
||||
x = wp[-2] ^ wp[-7] ^ wp[-13] ^ wp[-15];
|
||||
wp[1] = (x<<1) | (x>>31);
|
||||
d += ((e<<5) | (e>>27)) + wp[1];
|
||||
d += 0x5a827999 + (((b^c)&a)^c);
|
||||
a = (a<<30)|(a>>2);
|
||||
|
||||
x = wp[-1] ^ wp[-6] ^ wp[-12] ^ wp[-14];
|
||||
wp[2] = (x<<1) | (x>>31);
|
||||
c += ((d<<5) | (d>>27)) + wp[2];
|
||||
c += 0x5a827999 + (((a^b)&e)^b);
|
||||
e = (e<<30)|(e>>2);
|
||||
|
||||
x = wp[0] ^ wp[-5] ^ wp[-11] ^ wp[-13];
|
||||
wp[3] = (x<<1) | (x>>31);
|
||||
b += ((c<<5) | (c>>27)) + wp[3];
|
||||
b += 0x5a827999 + (((e^a)&d)^a);
|
||||
d = (d<<30)|(d>>2);
|
||||
|
||||
x = wp[1] ^ wp[-4] ^ wp[-10] ^ wp[-12];
|
||||
wp[4] = (x<<1) | (x>>31);
|
||||
a += ((b<<5) | (b>>27)) + wp[4];
|
||||
a += 0x5a827999 + (((d^e)&c)^e);
|
||||
c = (c<<30)|(c>>2);
|
||||
|
||||
wp += 5;
|
||||
p += 4;
|
||||
|
||||
wend = w + 40;
|
||||
for(; wp < wend; wp += 5){
|
||||
x = wp[-3] ^ wp[-8] ^ wp[-14] ^ wp[-16];
|
||||
wp[0] = (x<<1) | (x>>31);
|
||||
e += ((a<<5) | (a>>27)) + wp[0];
|
||||
e += 0x6ed9eba1 + (b^c^d);
|
||||
b = (b<<30)|(b>>2);
|
||||
|
||||
x = wp[-2] ^ wp[-7] ^ wp[-13] ^ wp[-15];
|
||||
wp[1] = (x<<1) | (x>>31);
|
||||
d += ((e<<5) | (e>>27)) + wp[1];
|
||||
d += 0x6ed9eba1 + (a^b^c);
|
||||
a = (a<<30)|(a>>2);
|
||||
|
||||
x = wp[-1] ^ wp[-6] ^ wp[-12] ^ wp[-14];
|
||||
wp[2] = (x<<1) | (x>>31);
|
||||
c += ((d<<5) | (d>>27)) + wp[2];
|
||||
c += 0x6ed9eba1 + (e^a^b);
|
||||
e = (e<<30)|(e>>2);
|
||||
|
||||
x = wp[0] ^ wp[-5] ^ wp[-11] ^ wp[-13];
|
||||
wp[3] = (x<<1) | (x>>31);
|
||||
b += ((c<<5) | (c>>27)) + wp[3];
|
||||
b += 0x6ed9eba1 + (d^e^a);
|
||||
d = (d<<30)|(d>>2);
|
||||
|
||||
x = wp[1] ^ wp[-4] ^ wp[-10] ^ wp[-12];
|
||||
wp[4] = (x<<1) | (x>>31);
|
||||
a += ((b<<5) | (b>>27)) + wp[4];
|
||||
a += 0x6ed9eba1 + (c^d^e);
|
||||
c = (c<<30)|(c>>2);
|
||||
}
|
||||
|
||||
wend = w + 60;
|
||||
for(; wp < wend; wp += 5){
|
||||
x = wp[-3] ^ wp[-8] ^ wp[-14] ^ wp[-16];
|
||||
wp[0] = (x<<1) | (x>>31);
|
||||
e += ((a<<5) | (a>>27)) + wp[0];
|
||||
e += 0x8f1bbcdc + ((b&c)|((b|c)&d));
|
||||
b = (b<<30)|(b>>2);
|
||||
|
||||
x = wp[-2] ^ wp[-7] ^ wp[-13] ^ wp[-15];
|
||||
wp[1] = (x<<1) | (x>>31);
|
||||
d += ((e<<5) | (e>>27)) + wp[1];
|
||||
d += 0x8f1bbcdc + ((a&b)|((a|b)&c));
|
||||
a = (a<<30)|(a>>2);
|
||||
|
||||
x = wp[-1] ^ wp[-6] ^ wp[-12] ^ wp[-14];
|
||||
wp[2] = (x<<1) | (x>>31);
|
||||
c += ((d<<5) | (d>>27)) + wp[2];
|
||||
c += 0x8f1bbcdc + ((e&a)|((e|a)&b));
|
||||
e = (e<<30)|(e>>2);
|
||||
|
||||
x = wp[0] ^ wp[-5] ^ wp[-11] ^ wp[-13];
|
||||
wp[3] = (x<<1) | (x>>31);
|
||||
b += ((c<<5) | (c>>27)) + wp[3];
|
||||
b += 0x8f1bbcdc + ((d&e)|((d|e)&a));
|
||||
d = (d<<30)|(d>>2);
|
||||
|
||||
x = wp[1] ^ wp[-4] ^ wp[-10] ^ wp[-12];
|
||||
wp[4] = (x<<1) | (x>>31);
|
||||
a += ((b<<5) | (b>>27)) + wp[4];
|
||||
a += 0x8f1bbcdc + ((c&d)|((c|d)&e));
|
||||
c = (c<<30)|(c>>2);
|
||||
}
|
||||
|
||||
wend = w + 80;
|
||||
for(; wp < wend; wp += 5){
|
||||
x = wp[-3] ^ wp[-8] ^ wp[-14] ^ wp[-16];
|
||||
wp[0] = (x<<1) | (x>>31);
|
||||
e += ((a<<5) | (a>>27)) + wp[0];
|
||||
e += 0xca62c1d6 + (b^c^d);
|
||||
b = (b<<30)|(b>>2);
|
||||
|
||||
x = wp[-2] ^ wp[-7] ^ wp[-13] ^ wp[-15];
|
||||
wp[1] = (x<<1) | (x>>31);
|
||||
d += ((e<<5) | (e>>27)) + wp[1];
|
||||
d += 0xca62c1d6 + (a^b^c);
|
||||
a = (a<<30)|(a>>2);
|
||||
|
||||
x = wp[-1] ^ wp[-6] ^ wp[-12] ^ wp[-14];
|
||||
wp[2] = (x<<1) | (x>>31);
|
||||
c += ((d<<5) | (d>>27)) + wp[2];
|
||||
c += 0xca62c1d6 + (e^a^b);
|
||||
e = (e<<30)|(e>>2);
|
||||
|
||||
x = wp[0] ^ wp[-5] ^ wp[-11] ^ wp[-13];
|
||||
wp[3] = (x<<1) | (x>>31);
|
||||
b += ((c<<5) | (c>>27)) + wp[3];
|
||||
b += 0xca62c1d6 + (d^e^a);
|
||||
d = (d<<30)|(d>>2);
|
||||
|
||||
x = wp[1] ^ wp[-4] ^ wp[-10] ^ wp[-12];
|
||||
wp[4] = (x<<1) | (x>>31);
|
||||
a += ((b<<5) | (b>>27)) + wp[4];
|
||||
a += 0xca62c1d6 + (c^d^e);
|
||||
c = (c<<30)|(c>>2);
|
||||
}
|
||||
|
||||
/* save state */
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
}
|
||||
}
|
38
libsec/sha1pickle.c
Normal file
38
libsec/sha1pickle.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include "os.h"
|
||||
#include <libsec.h>
|
||||
|
||||
char*
|
||||
sha1pickle(SHA1state *s)
|
||||
{
|
||||
char *p;
|
||||
int m, n;
|
||||
|
||||
m = 5*9+4*((s->blen+3)/3);
|
||||
p = malloc(m);
|
||||
if(p == nil)
|
||||
return p;
|
||||
n = sprint(p, "%8.8ux %8.8ux %8.8ux %8.8ux %8.8ux ",
|
||||
s->state[0], s->state[1], s->state[2],
|
||||
s->state[3], s->state[4]);
|
||||
enc64(p+n, m-n, s->buf, s->blen);
|
||||
return p;
|
||||
}
|
||||
|
||||
SHA1state*
|
||||
sha1unpickle(char *p)
|
||||
{
|
||||
SHA1state *s;
|
||||
|
||||
s = malloc(sizeof(*s));
|
||||
if(s == nil)
|
||||
return nil;
|
||||
s->state[0] = strtoul(p, &p, 16);
|
||||
s->state[1] = strtoul(p, &p, 16);
|
||||
s->state[2] = strtoul(p, &p, 16);
|
||||
s->state[3] = strtoul(p, &p, 16);
|
||||
s->state[4] = strtoul(p, &p, 16);
|
||||
s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p));
|
||||
s->malloced = 1;
|
||||
s->seeded = 1;
|
||||
return s;
|
||||
}
|
1004
libsec/smallprimes.c
Normal file
1004
libsec/smallprimes.c
Normal file
File diff suppressed because it is too large
Load Diff
1039
libsec/smallprimetest.c
Normal file
1039
libsec/smallprimetest.c
Normal file
File diff suppressed because it is too large
Load Diff
97
libsec/thumb.c
Normal file
97
libsec/thumb.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include <auth.h>
|
||||
#include <mp.h>
|
||||
#include <libsec.h>
|
||||
|
||||
enum{ ThumbTab = 1<<10 };
|
||||
|
||||
static void *
|
||||
emalloc(int n)
|
||||
{
|
||||
void *p;
|
||||
if(n==0)
|
||||
n=1;
|
||||
p = malloc(n);
|
||||
if(p == nil){
|
||||
exits("out of memory");
|
||||
}
|
||||
memset(p, 0, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
freeThumbprints(Thumbprint *table)
|
||||
{
|
||||
Thumbprint *hd, *p, *q;
|
||||
for(hd = table; hd < table+ThumbTab; hd++){
|
||||
for(p = hd->next; p; p = q){
|
||||
q = p->next;
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
free(table);
|
||||
}
|
||||
|
||||
int
|
||||
okThumbprint(uchar *sum, Thumbprint *table)
|
||||
{
|
||||
Thumbprint *p;
|
||||
int i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
|
||||
|
||||
for(p = table[i].next; p; p = p->next)
|
||||
if(memcmp(sum, p->sha1, SHA1dlen) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab)
|
||||
{
|
||||
Thumbprint *entry;
|
||||
Biobuf *bin;
|
||||
char *line, *field[50];
|
||||
uchar sum[SHA1dlen];
|
||||
int i;
|
||||
|
||||
bin = Bopen(file, OREAD);
|
||||
if(bin == nil)
|
||||
return;
|
||||
for(; (line = Brdstr(bin, '\n', 1)) != 0; free(line)){
|
||||
if(tokenize(line, field, nelem(field)) < 2)
|
||||
continue;
|
||||
if(strcmp(field[0], "#include") == 0){
|
||||
loadThumbprints(field[1], table, crltab);
|
||||
continue;
|
||||
}
|
||||
if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", strlen("sha1=")) != 0)
|
||||
continue;
|
||||
field[1] += strlen("sha1=");
|
||||
dec16(sum, sizeof(sum), field[1], strlen(field[1]));
|
||||
if(crltab && okThumbprint(sum, crltab))
|
||||
continue;
|
||||
entry = (Thumbprint*)emalloc(sizeof(*entry));
|
||||
memcpy(entry->sha1, sum, SHA1dlen);
|
||||
i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
|
||||
entry->next = table[i].next;
|
||||
table[i].next = entry;
|
||||
}
|
||||
Bterm(bin);
|
||||
}
|
||||
|
||||
Thumbprint *
|
||||
initThumbprints(char *ok, char *crl)
|
||||
{
|
||||
Thumbprint *table, *crltab = nil;
|
||||
|
||||
if(crl){
|
||||
crltab = emalloc(ThumbTab * sizeof(*table));
|
||||
loadThumbprints(crl, crltab, nil);
|
||||
}
|
||||
table = emalloc(ThumbTab * sizeof(*table));
|
||||
loadThumbprints(ok, table, crltab);
|
||||
free(crltab);
|
||||
return table;
|
||||
}
|
||||
|
2291
libsec/tlshand.c
Normal file
2291
libsec/tlshand.c
Normal file
File diff suppressed because it is too large
Load Diff
2520
libsec/x509.c
Normal file
2520
libsec/x509.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user