17dd7cddfSDavid du Colombier #pragma lib "libsec.a" 27dd7cddfSDavid du Colombier #pragma src "/sys/src/libsec" 37dd7cddfSDavid du Colombier 47dd7cddfSDavid du Colombier #ifndef _MPINT 57dd7cddfSDavid du Colombier typedef struct mpint mpint; 67dd7cddfSDavid du Colombier #endif 77dd7cddfSDavid du Colombier 87dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 97dd7cddfSDavid du Colombier // DES definitions 107dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 117dd7cddfSDavid du Colombier 127dd7cddfSDavid du Colombier enum 137dd7cddfSDavid du Colombier { 14*59cc4ca5SDavid du Colombier DESbsize= 8 157dd7cddfSDavid du Colombier }; 167dd7cddfSDavid du Colombier 177dd7cddfSDavid du Colombier // single des 187dd7cddfSDavid du Colombier typedef struct DESstate DESstate; 197dd7cddfSDavid du Colombier struct DESstate 207dd7cddfSDavid du Colombier { 217dd7cddfSDavid du Colombier ulong setup; 227dd7cddfSDavid du Colombier uchar key[8]; /* unexpanded key */ 237dd7cddfSDavid du Colombier ulong expanded[32]; /* expanded key */ 247dd7cddfSDavid du Colombier uchar ivec[8]; /* initialization vector */ 257dd7cddfSDavid du Colombier }; 267dd7cddfSDavid du Colombier 277dd7cddfSDavid du Colombier void setupDESstate(DESstate *s, uchar key[8], uchar *ivec); 287dd7cddfSDavid du Colombier void des_key_setup(uchar[8], ulong[32]); 297dd7cddfSDavid du Colombier void block_cipher(ulong*, uchar*, int); 307dd7cddfSDavid du Colombier void desCBCencrypt(uchar*, int, DESstate*); 317dd7cddfSDavid du Colombier void desCBCdecrypt(uchar*, int, DESstate*); 327dd7cddfSDavid du Colombier void desECBencrypt(uchar*, int, DESstate*); 337dd7cddfSDavid du Colombier void desECBdecrypt(uchar*, int, DESstate*); 347dd7cddfSDavid du Colombier 357dd7cddfSDavid du Colombier // for backward compatibility with 7 byte DES key format 367dd7cddfSDavid du Colombier void des56to64(uchar *k56, uchar *k64); 377dd7cddfSDavid du Colombier void des64to56(uchar *k64, uchar *k56); 387dd7cddfSDavid du Colombier void key_setup(uchar[7], ulong[32]); 397dd7cddfSDavid du Colombier 407dd7cddfSDavid du Colombier // triple des encrypt/decrypt orderings 417dd7cddfSDavid du Colombier enum { 427dd7cddfSDavid du Colombier DES3E= 0, 437dd7cddfSDavid du Colombier DES3D= 1, 447dd7cddfSDavid du Colombier DES3EEE= 0, 457dd7cddfSDavid du Colombier DES3EDE= 2, 467dd7cddfSDavid du Colombier DES3DED= 5, 47*59cc4ca5SDavid du Colombier DES3DDD= 7 487dd7cddfSDavid du Colombier }; 497dd7cddfSDavid du Colombier 507dd7cddfSDavid du Colombier typedef struct DES3state DES3state; 517dd7cddfSDavid du Colombier struct DES3state 527dd7cddfSDavid du Colombier { 537dd7cddfSDavid du Colombier ulong setup; 547dd7cddfSDavid du Colombier uchar key[3][8]; /* unexpanded key */ 557dd7cddfSDavid du Colombier ulong expanded[3][32]; /* expanded key */ 567dd7cddfSDavid du Colombier uchar ivec[8]; /* initialization vector */ 577dd7cddfSDavid du Colombier }; 587dd7cddfSDavid du Colombier 597dd7cddfSDavid du Colombier void setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec); 607dd7cddfSDavid du Colombier void triple_block_cipher(ulong keys[3][32], uchar*, int); 617dd7cddfSDavid du Colombier void des3CBCencrypt(uchar*, int, DES3state*); 627dd7cddfSDavid du Colombier void des3CBCdecrypt(uchar*, int, DES3state*); 637dd7cddfSDavid du Colombier void des3ECBencrypt(uchar*, int, DES3state*); 647dd7cddfSDavid du Colombier void des3ECBdecrypt(uchar*, int, DES3state*); 657dd7cddfSDavid du Colombier 667dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 677dd7cddfSDavid du Colombier // digests 687dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 697dd7cddfSDavid du Colombier 707dd7cddfSDavid du Colombier enum 717dd7cddfSDavid du Colombier { 727dd7cddfSDavid du Colombier SHA1dlen= 20, /* SHA digest length */ 737dd7cddfSDavid du Colombier MD4dlen= 16, /* MD4 digest length */ 747dd7cddfSDavid du Colombier MD5dlen= 16 /* MD5 digest length */ 757dd7cddfSDavid du Colombier }; 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier typedef struct DigestState DigestState; 787dd7cddfSDavid du Colombier struct DigestState 797dd7cddfSDavid du Colombier { 807dd7cddfSDavid du Colombier ulong len; 817dd7cddfSDavid du Colombier u32int state[5]; 827dd7cddfSDavid du Colombier uchar buf[128]; 837dd7cddfSDavid du Colombier int blen; 847dd7cddfSDavid du Colombier char malloced; 857dd7cddfSDavid du Colombier char seeded; 867dd7cddfSDavid du Colombier }; 87*59cc4ca5SDavid du Colombier typedef struct DigestState SHAstate; /* obsolete name */ 88*59cc4ca5SDavid du Colombier typedef struct DigestState SHA1state; 897dd7cddfSDavid du Colombier typedef struct DigestState MD5state; 907dd7cddfSDavid du Colombier typedef struct DigestState MD4state; 917dd7cddfSDavid du Colombier 927dd7cddfSDavid du Colombier DigestState* md4(uchar*, ulong, uchar*, DigestState*); 937dd7cddfSDavid du Colombier DigestState* md5(uchar*, ulong, uchar*, DigestState*); 947dd7cddfSDavid du Colombier DigestState* sha1(uchar*, ulong, uchar*, DigestState*); 957dd7cddfSDavid du Colombier DigestState* hmac_md5(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); 967dd7cddfSDavid du Colombier DigestState* hmac_sha1(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); 977dd7cddfSDavid du Colombier 987dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 997dd7cddfSDavid du Colombier // base 64 & 32 conversions 1007dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1017dd7cddfSDavid du Colombier 1027dd7cddfSDavid du Colombier int dec64(uchar *out, int lim, char *in, int n); 1037dd7cddfSDavid du Colombier int enc64(char *out, int lim, uchar *in, int n); 1047dd7cddfSDavid du Colombier int dec32(uchar *out, int lim, char *in, int n); 1057dd7cddfSDavid du Colombier int enc32(char *out, int lim, uchar *in, int n); 1067dd7cddfSDavid du Colombier 1077dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1087dd7cddfSDavid du Colombier // random number generation 1097dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1107dd7cddfSDavid du Colombier void genrandom(uchar *buf, int nbytes); 1117dd7cddfSDavid du Colombier void prng(uchar *buf, int nbytes); 1127dd7cddfSDavid du Colombier 1137dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1147dd7cddfSDavid du Colombier // primes 1157dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1167dd7cddfSDavid du Colombier void genprime(mpint *p, int n, int accuracy); // generate an n bit probable prime 1177dd7cddfSDavid du Colombier void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy); // prime and generator 1187dd7cddfSDavid du Colombier void genstrongprime(mpint *p, int n, int accuracy); // generate an n bit strong prime 1197dd7cddfSDavid du Colombier void DSAprimes(mpint *q, mpint *p, uchar seed[SHA1dlen]); 1207dd7cddfSDavid du Colombier int probably_prime(mpint *n, int nrep); // miller-rabin test 1217dd7cddfSDavid du Colombier int smallprimetest(mpint *p); // returns -1 if not prime, 0 otherwise 1227dd7cddfSDavid du Colombier 1237dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1247dd7cddfSDavid du Colombier // rc4 1257dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1267dd7cddfSDavid du Colombier typedef struct RC4state RC4state; 1277dd7cddfSDavid du Colombier struct RC4state 1287dd7cddfSDavid du Colombier { 1297dd7cddfSDavid du Colombier uchar state[256]; 1307dd7cddfSDavid du Colombier uchar x; 1317dd7cddfSDavid du Colombier uchar y; 1327dd7cddfSDavid du Colombier }; 1337dd7cddfSDavid du Colombier 1347dd7cddfSDavid du Colombier void setupRC4state(RC4state*, uchar*, int); 1357dd7cddfSDavid du Colombier void rc4(RC4state*, uchar*, int); 1367dd7cddfSDavid du Colombier void rc4skip(RC4state*, int); 1377dd7cddfSDavid du Colombier void rc4back(RC4state*, int); 1387dd7cddfSDavid du Colombier 1397dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1407dd7cddfSDavid du Colombier // rsa 1417dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1427dd7cddfSDavid du Colombier typedef struct RSApub RSApub; 1437dd7cddfSDavid du Colombier typedef struct RSApriv RSApriv; 1447dd7cddfSDavid du Colombier 1457dd7cddfSDavid du Colombier // public/encryption key 1467dd7cddfSDavid du Colombier struct RSApub 1477dd7cddfSDavid du Colombier { 1487dd7cddfSDavid du Colombier mpint *n; // modulus 1497dd7cddfSDavid du Colombier mpint *ek; // exp (encryption key) 1507dd7cddfSDavid du Colombier }; 1517dd7cddfSDavid du Colombier 1527dd7cddfSDavid du Colombier // private/decryption key 1537dd7cddfSDavid du Colombier struct RSApriv 1547dd7cddfSDavid du Colombier { 1557dd7cddfSDavid du Colombier RSApub pub; 1567dd7cddfSDavid du Colombier 1577dd7cddfSDavid du Colombier mpint *dk; // exp (decryption key) 1587dd7cddfSDavid du Colombier 1597dd7cddfSDavid du Colombier // precomputed values to help with chinese remainder theorem calc 1607dd7cddfSDavid du Colombier mpint *p; 1617dd7cddfSDavid du Colombier mpint *q; 1627dd7cddfSDavid du Colombier mpint *kp; // dk mod p-1 1637dd7cddfSDavid du Colombier mpint *kq; // dk mod q-1 1647dd7cddfSDavid du Colombier mpint *c2; // for converting modular rep to answer 1657dd7cddfSDavid du Colombier }; 1667dd7cddfSDavid du Colombier 1677dd7cddfSDavid du Colombier RSApriv* rsagen(int nlen, int elen, int rounds); 1687dd7cddfSDavid du Colombier mpint* rsaencrypt(RSApub *k, mpint *in, mpint *out); 1697dd7cddfSDavid du Colombier mpint* rsadecrypt(RSApriv *k, mpint *in, mpint *out); 1707dd7cddfSDavid du Colombier RSApub* rsapuballoc(void); 1717dd7cddfSDavid du Colombier void rsapubfree(RSApub*); 1727dd7cddfSDavid du Colombier RSApriv* rsaprivalloc(void); 1737dd7cddfSDavid du Colombier void rsaprivfree(RSApriv*); 1747dd7cddfSDavid du Colombier RSApub* rsaprivtopub(RSApriv*); 1757dd7cddfSDavid du Colombier 1767dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1777dd7cddfSDavid du Colombier // eg 1787dd7cddfSDavid du Colombier ///////////////////////////////////////////////////////// 1797dd7cddfSDavid du Colombier typedef struct EGpub EGpub; 1807dd7cddfSDavid du Colombier typedef struct EGpriv EGpriv; 1817dd7cddfSDavid du Colombier typedef struct EGsig EGsig; 1827dd7cddfSDavid du Colombier 1837dd7cddfSDavid du Colombier // public/encryption key 1847dd7cddfSDavid du Colombier struct EGpub 1857dd7cddfSDavid du Colombier { 1867dd7cddfSDavid du Colombier mpint *p; // modulus 1877dd7cddfSDavid du Colombier mpint *alpha; // generator 1887dd7cddfSDavid du Colombier mpint *key; // (encryption key) alpha**secret mod p 1897dd7cddfSDavid du Colombier }; 1907dd7cddfSDavid du Colombier 1917dd7cddfSDavid du Colombier // private/decryption key 1927dd7cddfSDavid du Colombier struct EGpriv 1937dd7cddfSDavid du Colombier { 1947dd7cddfSDavid du Colombier EGpub pub; 1957dd7cddfSDavid du Colombier mpint *secret; // (decryption key) 1967dd7cddfSDavid du Colombier }; 1977dd7cddfSDavid du Colombier 1987dd7cddfSDavid du Colombier // signature 1997dd7cddfSDavid du Colombier struct EGsig 2007dd7cddfSDavid du Colombier { 2017dd7cddfSDavid du Colombier mpint *r, *s; 2027dd7cddfSDavid du Colombier }; 2037dd7cddfSDavid du Colombier 2047dd7cddfSDavid du Colombier EGpriv* eggen(int nlen, int rounds); 2057dd7cddfSDavid du Colombier mpint* egencrypt(EGpub *k, mpint *in, mpint *out); 2067dd7cddfSDavid du Colombier mpint* egdecrypt(EGpriv *k, mpint *in, mpint *out); 2077dd7cddfSDavid du Colombier EGsig* egsign(EGpriv *k, mpint *m); 2087dd7cddfSDavid du Colombier int egverify(EGpub *k, EGsig *sig, mpint *m); 2097dd7cddfSDavid du Colombier EGpub* egpuballoc(void); 2107dd7cddfSDavid du Colombier void egpubfree(EGpub*); 2117dd7cddfSDavid du Colombier EGpriv* egprivalloc(void); 2127dd7cddfSDavid du Colombier void egprivfree(EGpriv*); 2137dd7cddfSDavid du Colombier EGsig* egsigalloc(void); 2147dd7cddfSDavid du Colombier void egsigfree(EGsig*); 2157dd7cddfSDavid du Colombier EGpub* egprivtopub(EGpriv*); 216