Add most of libsec.
This commit is contained in:
parent
768206abfc
commit
0fc65b37a1
47 changed files with 9625 additions and 0 deletions
579
src/libsec/port/blowfish.c
Normal file
579
src/libsec/port/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,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
61
src/libsec/port/decodepem.c
Normal file
61
src/libsec/port/decodepem.c
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
*len = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
59
src/libsec/port/des3CBC.c
Normal file
59
src/libsec/port/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
src/libsec/port/des3ECB.c
Normal file
48
src/libsec/port/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
src/libsec/port/desCBC.c
Normal file
59
src/libsec/port/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
src/libsec/port/desECB.c
Normal file
48
src/libsec/port/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];
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/libsec/port/dsaalloc.c
Normal file
72
src/libsec/port/dsaalloc.c
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#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);
|
||||||
|
free(dsa);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(dsa);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(dsa);
|
||||||
|
}
|
||||||
58
src/libsec/port/dsagen.c
Normal file
58
src/libsec/port/dsagen.c
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#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.
|
||||||
|
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
src/libsec/port/dsaprimes.c
Normal file
97
src/libsec/port/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
src/libsec/port/dsaprivtopub.c
Normal file
16
src/libsec/port/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
src/libsec/port/dsasign.c
Normal file
52
src/libsec/port/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, pub->q) >= 0))
|
||||||
|
continue;
|
||||||
|
mpextendedgcd(k, q, r, kinv, s);
|
||||||
|
if(mpcmp(r, mpone) != 0)
|
||||||
|
sysfatal("dsasign: pub->q not prime");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make kinv positive
|
||||||
|
mpmod(kinv, pub->q, 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
src/libsec/port/dsaverify.c
Normal file
46
src/libsec/port/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(mpcmp(sig->r, mpone) < 0 || mpcmp(sig->r, pub->q) >= 0)
|
||||||
|
return rv;
|
||||||
|
if(mpcmp(sig->s, mpone) < 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;
|
||||||
|
}
|
||||||
70
src/libsec/port/egalloc.c
Normal file
70
src/libsec/port/egalloc.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#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);
|
||||||
|
free(eg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(eg);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
free(eg);
|
||||||
|
}
|
||||||
28
src/libsec/port/egdecrypt.c
Normal file
28
src/libsec/port/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
src/libsec/port/egencrypt.c
Normal file
38
src/libsec/port/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
src/libsec/port/eggen.c
Normal file
21
src/libsec/port/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
src/libsec/port/egprivtopub.c
Normal file
17
src/libsec/port/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
src/libsec/port/egsign.c
Normal file
43
src/libsec/port/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
src/libsec/port/egtest.c
Normal file
34
src/libsec/port/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
src/libsec/port/egverify.c
Normal file
29
src/libsec/port/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;
|
||||||
|
}
|
||||||
27
src/libsec/port/genprime.c
Normal file
27
src/libsec/port/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);
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/libsec/port/gensafeprime.c
Normal file
36
src/libsec/port/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
src/libsec/port/genstrongprime.c
Normal file
57
src/libsec/port/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
src/libsec/port/hmac.c
Normal file
56
src/libsec/port/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
src/libsec/port/hmactest.c
Normal file
19
src/libsec/port/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
src/libsec/port/md4.c
Normal file
271
src/libsec/port/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
src/libsec/port/md4test.c
Normal file
31
src/libsec/port/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");
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/libsec/port/md5pickle.c
Normal file
37
src/libsec/port/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;
|
||||||
|
}
|
||||||
23
src/libsec/port/nfastrand.c
Normal file
23
src/libsec/port/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)
|
||||||
|
sysfatal("nfastrand: n too large");
|
||||||
|
|
||||||
|
m = Maxrand - Maxrand % n;
|
||||||
|
while((r = fastrand()) >= m)
|
||||||
|
;
|
||||||
|
return r%n;
|
||||||
|
}
|
||||||
41
src/libsec/port/primetest.c
Normal file
41
src/libsec/port/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
src/libsec/port/prng.c
Normal file
15
src/libsec/port/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
src/libsec/port/probably_prime.c
Normal file
84
src/libsec/port/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;
|
||||||
|
}
|
||||||
104
src/libsec/port/rc4.c
Normal file
104
src/libsec/port/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;
|
||||||
|
}
|
||||||
51
src/libsec/port/readcert.c
Normal file
51
src/libsec/port/readcert.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <auth.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
src/libsec/port/rsaalloc.c
Normal file
52
src/libsec/port/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
src/libsec/port/rsadecrypt.c
Normal file
37
src/libsec/port/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
src/libsec/port/rsaencrypt.c
Normal file
12
src/libsec/port/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
src/libsec/port/rsafill.c
Normal file
61
src/libsec/port/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;
|
||||||
|
}
|
||||||
|
|
||||||
70
src/libsec/port/rsagen.c
Normal file
70
src/libsec/port/rsagen.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "os.h"
|
||||||
|
#include <mp.h>
|
||||||
|
#include <libsec.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
genprime(p, nlen/2, rounds);
|
||||||
|
genprime(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);
|
||||||
|
mprand(elen, genrandom, e);
|
||||||
|
if(mpcmp(e,mptwo) <= 0)
|
||||||
|
itomp(3, e);
|
||||||
|
// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
|
||||||
|
// of the merits of various choices of primes and exponents. e=3 is a
|
||||||
|
// common and recommended exponent, but doesn't necessarily work here
|
||||||
|
// because we chose strong rather than safe primes.
|
||||||
|
for(;;){
|
||||||
|
mpextendedgcd(e, phi, t1, d, t2);
|
||||||
|
if(mpcmp(t1, mpone) == 0)
|
||||||
|
break;
|
||||||
|
mpadd(mpone, e, e);
|
||||||
|
}
|
||||||
|
mpfree(t1);
|
||||||
|
mpfree(t2);
|
||||||
|
|
||||||
|
// 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
src/libsec/port/rsaprivtopub.c
Normal file
16
src/libsec/port/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
src/libsec/port/rsatest.c
Normal file
57
src/libsec/port/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("> ");
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/libsec/port/sha1pickle.c
Normal file
38
src/libsec/port/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
src/libsec/port/smallprimes.c
Normal file
1004
src/libsec/port/smallprimes.c
Normal file
File diff suppressed because it is too large
Load diff
1039
src/libsec/port/smallprimetest.c
Normal file
1039
src/libsec/port/smallprimetest.c
Normal file
File diff suppressed because it is too large
Load diff
97
src/libsec/port/thumb.c
Normal file
97
src/libsec/port/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
src/libsec/port/tlshand.c
Normal file
2291
src/libsec/port/tlshand.c
Normal file
File diff suppressed because it is too large
Load diff
2524
src/libsec/port/x509.c
Normal file
2524
src/libsec/port/x509.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue