1/* 2 * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 3 * 4 * Extracted from chap_ms.c by James Carlson. 5 * 6 * Copyright (c) 1995 Eric Rosenquist. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name(s) of the authors of this software must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. 23 * 24 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 25 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 26 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 27 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 29 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 30 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 */ 32 33#include <errno.h> 34#include "pppd.h" 35#include "pppcrypt.h" 36 37static u_char 38Get7Bits(input, startBit) 39u_char *input; 40int startBit; 41{ 42 unsigned int word; 43 44 word = (unsigned)input[startBit / 8] << 8; 45 word |= (unsigned)input[startBit / 8 + 1]; 46 47 word >>= 15 - (startBit % 8 + 7); 48 49 return word & 0xFE; 50} 51 52static void 53MakeKey(key, des_key) 54u_char *key; /* IN 56 bit DES key missing parity bits */ 55u_char *des_key; /* OUT 64 bit DES key with parity bits added */ 56{ 57 des_key[0] = Get7Bits(key, 0); 58 des_key[1] = Get7Bits(key, 7); 59 des_key[2] = Get7Bits(key, 14); 60 des_key[3] = Get7Bits(key, 21); 61 des_key[4] = Get7Bits(key, 28); 62 des_key[5] = Get7Bits(key, 35); 63 des_key[6] = Get7Bits(key, 42); 64 des_key[7] = Get7Bits(key, 49); 65 66#ifndef USE_CRYPT 67 des_set_odd_parity((des_cblock *)des_key); 68#endif 69} 70 71#ifdef USE_CRYPT 72/* 73 * in == 8-byte string (expanded version of the 56-bit key) 74 * out == 64-byte string where each byte is either 1 or 0 75 * Note that the low-order "bit" is always ignored by by setkey() 76 */ 77static void 78Expand(in, out) 79u_char *in; 80u_char *out; 81{ 82 int j, c; 83 int i; 84 85 for (i = 0; i < 64; in++){ 86 c = *in; 87 for (j = 7; j >= 0; j--) 88 *out++ = (c >> j) & 01; 89 i += 8; 90 } 91} 92 93/* The inverse of Expand 94 */ 95static void 96Collapse(in, out) 97u_char *in; 98u_char *out; 99{ 100 int j; 101 int i; 102 unsigned int c; 103 104 for (i = 0; i < 64; i += 8, out++) { 105 c = 0; 106 for (j = 7; j >= 0; j--, in++) 107 c |= *in << j; 108 *out = c & 0xff; 109 } 110} 111 112bool 113DesSetkey(key) 114u_char *key; 115{ 116 u_char des_key[8]; 117 u_char crypt_key[66]; 118 119 MakeKey(key, des_key); 120 Expand(des_key, crypt_key); 121 errno = 0; 122 setkey((const char *)crypt_key); 123 if (errno != 0) 124 return (0); 125 return (1); 126} 127 128bool 129DesEncrypt(clear, cipher) 130u_char *clear; /* IN 8 octets */ 131u_char *cipher; /* OUT 8 octets */ 132{ 133 u_char des_input[66]; 134 135 Expand(clear, des_input); 136 errno = 0; 137 encrypt((char *)des_input, 0); 138 if (errno != 0) 139 return (0); 140 Collapse(des_input, cipher); 141 return (1); 142} 143 144bool 145DesDecrypt(cipher, clear) 146u_char *cipher; /* IN 8 octets */ 147u_char *clear; /* OUT 8 octets */ 148{ 149 u_char des_input[66]; 150 151 Expand(cipher, des_input); 152 errno = 0; 153 encrypt((char *)des_input, 1); 154 if (errno != 0) 155 return (0); 156 Collapse(des_input, clear); 157 return (1); 158} 159 160#else /* USE_CRYPT */ 161static des_key_schedule key_schedule; 162 163bool 164DesSetkey(key) 165u_char *key; 166{ 167 des_cblock des_key; 168 MakeKey(key, des_key); 169 des_set_key(&des_key, key_schedule); 170 return (1); 171} 172 173bool 174DesEncrypt(clear, cipher) 175u_char *clear; /* IN 8 octets */ 176u_char *cipher; /* OUT 8 octets */ 177{ 178 des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, 179 key_schedule, 1); 180 return (1); 181} 182 183bool 184DesDecrypt(cipher, clear) 185u_char *cipher; /* IN 8 octets */ 186u_char *clear; /* OUT 8 octets */ 187{ 188 des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, 189 key_schedule, 0); 190 return (1); 191} 192 193#endif /* USE_CRYPT */ 194