1/* 2 * ppp_mppe_crypto.c - cryptografic funtions for MPPE 3 * 4 * This code is Public Domain. Please see comments below. 5 * 6 * I have just put SHA1 and ARCFOUR implementations into one file 7 * in order to not pollute kernel namespace. 8 * 9 * Jan Dubiec <jdx@slackware.pl>, 2003-07-08 10 */ 11 12/* 13 * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c 14 * 15 * SHA-1 in C 16 * By Steve Reid <steve@edmweb.com> 17 * 100% Public Domain 18 * 19 * Test Vectors (from FIPS PUB 180-1) 20 * "abc" 21 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 22 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 23 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 24 * A million repetitions of "a" 25 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 26 */ 27 28/* #define SHA1HANDSOFF * Copies data before messing with it. */ 29 30#if defined(__linux__) 31#include <asm/byteorder.h> 32#include <linux/string.h> 33#elif defined(__solaris__) 34#include <sys/isa_defs.h> 35#include <sys/ddi.h> 36#include <sys/sunddi.h> 37#define memcpy(d, s, c) bcopy(s, d, c) 38#define memset(d, b, c) bzero(d, c) 39#endif 40 41#include "ppp_mppe_crypto.h" 42 43static void SHA1_Transform(unsigned long[5], const unsigned char[64]); 44 45#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 46 47/* blk0() and blk() perform the initial expand. */ 48/* I got the idea of expanding during the round function from SSLeay */ 49#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN) 50#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 51 |(rol(block->l[i],8)&0x00FF00FF)) 52#elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) 53#define blk0(i) block->l[i] 54#else 55#error Endianness not defined 56#endif 57#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 58 ^block->l[(i+2)&15]^block->l[i&15],1)) 59 60/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 61#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 62#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 63#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 64#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 65#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 66 67/* Hash a single 512-bit block. This is the core of the algorithm. */ 68static void 69SHA1_Transform(unsigned long state[5], const unsigned char buffer[64]) 70{ 71 unsigned long a, b, c, d, e; 72 typedef union { 73 unsigned char c[64]; 74 unsigned long l[16]; 75 } CHAR64LONG16; 76 CHAR64LONG16 *block; 77 78#ifdef SHA1HANDSOFF 79 static unsigned char workspace[64]; 80 block = (CHAR64LONG16 *) workspace; 81 memcpy(block, buffer, 64); 82#else 83 block = (CHAR64LONG16 *) buffer; 84#endif 85 /* Copy context->state[] to working vars */ 86 a = state[0]; 87 b = state[1]; 88 c = state[2]; 89 d = state[3]; 90 e = state[4]; 91 /* 4 rounds of 20 operations each. Loop unrolled. */ 92 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 93 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 94 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 95 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 96 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 97 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 98 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 99 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 100 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 101 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 102 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 103 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 104 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 105 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 106 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 107 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 108 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 109 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 110 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 111 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 112 /* Add the working vars back into context.state[] */ 113 state[0] += a; 114 state[1] += b; 115 state[2] += c; 116 state[3] += d; 117 state[4] += e; 118 /* Wipe variables */ 119 a = b = c = d = e = 0; 120} 121 122/* SHA1Init - Initialize new context */ 123void 124SHA1_Init(SHA1_CTX *context) 125{ 126 /* SHA1 initialization constants */ 127 context->state[0] = 0x67452301; 128 context->state[1] = 0xEFCDAB89; 129 context->state[2] = 0x98BADCFE; 130 context->state[3] = 0x10325476; 131 context->state[4] = 0xC3D2E1F0; 132 context->count[0] = context->count[1] = 0; 133} 134 135/* Run your data through this. */ 136void 137SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len) 138{ 139 unsigned int i, j; 140 141 j = (context->count[0] >> 3) & 63; 142 if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; 143 context->count[1] += (len >> 29); 144 if ((j + len) > 63) { 145 memcpy(&context->buffer[j], data, (i = 64-j)); 146 SHA1_Transform(context->state, context->buffer); 147 for ( ; i + 63 < len; i += 64) { 148 SHA1_Transform(context->state, &data[i]); 149 } 150 j = 0; 151 } 152 else 153 i = 0; 154 155 memcpy(&context->buffer[j], &data[i], len - i); 156} 157 158/* Add padding and return the message digest. */ 159void 160SHA1_Final(unsigned char digest[20], SHA1_CTX *context) 161{ 162 unsigned long i, j; 163 unsigned char finalcount[8]; 164 165 for (i = 0; i < 8; i++) { 166 finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 167 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 168 } 169 SHA1_Update(context, (unsigned char *) "\200", 1); 170 while ((context->count[0] & 504) != 448) { 171 SHA1_Update(context, (unsigned char *) "\0", 1); 172 } 173 SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 174 for (i = 0; i < 20; i++) { 175 digest[i] = (unsigned char) 176 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 177 } 178 /* Wipe variables */ 179 i = j = 0; 180 memset(context->buffer, 0, 64); 181 memset(context->state, 0, 20); 182 memset(context->count, 0, 8); 183 memset(&finalcount, 0, 8); 184#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ 185 SHA1Transform(context->state, context->buffer); 186#endif 187} 188 189/* 190 * arcfour.c 191 * by Frank Cusack <frank@google.com> 192 * 100% public domain 193 * 194 * Implemented from the description in _Applied Cryptography_, 2nd ed. 195 * 196 * ** Distribution ** of this software is unlimited and unrestricted. 197 * 198 * ** Use ** of this software is almost certainly legal; however, refer 199 * to <http://theory.lcs.mit.edu/~rivest/faq.html>. 200 */ 201 202#define swap(a, b) \ 203{ \ 204 unsigned char t = b; \ 205 b = a; \ 206 a = t; \ 207} 208 209/* 210 * Initialize arcfour from a key. 211 */ 212void 213arcfour_setkey(arcfour_context *context, const unsigned char *key, 214 unsigned keylen) 215{ 216 unsigned i, j; 217 unsigned char K[256]; 218 219 context->i = context->j = 0; 220 221 for (i = 0; i < 256; i++) { 222 context->S[i] = i; 223 K[i] = key[i % keylen]; 224 } 225 226 j = 0; 227 for (i = 0; i < 256; i++) { 228 j = (j + context->S[i] + K[i]) % 256; 229 swap(context->S[i], context->S[j]); 230 } 231 232 memset(K, 0, sizeof(K)); 233} 234 235/* 236 * plaintext -> ciphertext (or vice versa) 237 */ 238void 239arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len, 240 unsigned char *out) 241{ 242 unsigned i = context->i; 243 unsigned j = context->j; 244 unsigned char *S = context->S; 245 unsigned char K; 246 247 while (len--) { 248 i = (i + 1) % 256; 249 j = (j + S[i]) % 256; 250 swap(S[i], S[j]); 251 K = S[(S[i] + S[j]) % 256]; 252 *out++ = *in++ ^ K; 253 } 254 255 context->i = i; 256 context->j = j; 257} 258