blob: 45fedb009fb15c58fa2b0481db604486fbd87e6d [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*
2 * Copyright (c) Tim Hockin, Cobalt Networks Inc. and others
3 *
4 * crypto routines used by multiple c files
5 */
6#include <stdio.h>
7#include <ctype.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <string.h>
11#include "extra_crypto.h"
12#include "pppd.h"
13#include "md4.h"
14#ifndef USE_CRYPT
15#include <des.h>
16#endif
17
18/* quick wrapper for easy md4 */
19void
20md4(unsigned char *from, int from_len, unsigned char *to)
21{
22 MD4_CTX Context;
23
24#ifndef __NetBSD__
25 from_len <<= 3; /* bytes->bits */
26#endif
27
28 MD4Init(&Context);
29 MD4Update(&Context, from, from_len);
30 MD4Final(to, &Context);
31}
32
33
34/* Microsoft LANMAN Password hashing */
35static u_char *MSStdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
36
37void
38LmPasswordHash(char *password, int len, char *hash)
39{
40 int i;
41 u_char up_pass[MAX_NT_PASSWORD]; /* max is actually 14 */
42
43 /* LANMan password is case insensitive */
44 BZERO(up_pass, sizeof(up_pass));
45 for (i = 0; i < len; i++)
46 up_pass[i] = (u_char)toupper(up_pass[i]);
47 DesEncrypt(MSStdText, up_pass + 0, hash + 0);
48 DesEncrypt(MSStdText, up_pass + 7, hash + 8);
49}
50
51void
52NtPasswordHash(char *secret, int secret_len, unsigned char *hash)
53{
54 int i;
55 u_char unicodePassword[MAX_NT_PASSWORD * 2];
56
57 /* Initialize the Unicode version of the secret (== password). */
58 /* This implicitly supports 8-bit ISO8859/1 characters. */
59 BZERO(unicodePassword, sizeof(unicodePassword));
60 for (i = 0; i < secret_len; i++)
61 unicodePassword[i * 2] = (u_char)secret[i];
62
63 /* Unicode is 2 bytes per char */
64 md4(unicodePassword, secret_len * 2, hash);
65}
66
67
68static u_char Get7Bits(unsigned char *input, int startBit)
69{
70 register unsigned int word;
71
72 word = (unsigned)input[startBit / 8] << 8;
73 word |= (unsigned)input[startBit / 8 + 1];
74
75 word >>= 15 - (startBit % 8 + 7);
76
77 return word & 0xFE;
78}
79
80
81static void MakeKey(unsigned char *key, unsigned char *des_key)
82{
83 des_key[0] = Get7Bits(key, 0);
84 des_key[1] = Get7Bits(key, 7);
85 des_key[2] = Get7Bits(key, 14);
86 des_key[3] = Get7Bits(key, 21);
87 des_key[4] = Get7Bits(key, 28);
88 des_key[5] = Get7Bits(key, 35);
89 des_key[6] = Get7Bits(key, 42);
90 des_key[7] = Get7Bits(key, 49);
91
92#ifndef USE_CRYPT
93 des_set_odd_parity((des_cblock *)des_key);
94#endif
95}
96
97
98#ifdef USE_CRYPT
99/* in == 8-byte string (expanded version of the 56-bit key)
100 * out == 64-byte string where each byte is either 1 or 0
101 * Note that the low-order "bit" is always ignored by by setkey()
102 */
103static void Expand(unsigned char *in, unsigned char *out)
104{
105 int j, c;
106 int i;
107
108 for(i = 0; i < 64; in++){
109 c = *in;
110 for(j = 7; j >= 0; j--)
111 *out++ = (c >> j) & 01;
112 i += 8;
113 }
114}
115
116/* The inverse of Expand
117 */
118static void Collapse(unsigned char *in, unsigned char *out)
119{
120 int j;
121 int i;
122 unsigned int c;
123
124 for (i = 0; i < 64; i += 8, out++) {
125 c = 0;
126 for (j = 7; j >= 0; j--, in++)
127 c |= *in << j;
128 *out = c & 0xff;
129 }
130}
131void
132DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
133{
134 u_char des_key[8];
135 u_char crypt_key[66];
136 u_char des_input[66];
137
138 MakeKey(key, des_key);
139
140 Expand(des_key, crypt_key);
141 setkey(crypt_key);
142
143 Expand(clear, des_input);
144 encrypt(des_input, 0);
145 Collapse(des_input, cipher);
146}
147#else /* don't USE_CRYPT */
148void
149DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher)
150{
151 des_cblock des_key;
152 des_key_schedule key_schedule;
153
154 MakeKey(key, des_key);
155
156 des_set_key(&des_key, key_schedule);
157
158 des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
159}
160#endif /* USE_CRYPT */
161
162