374330e2 |
1 | /* |
2 | * RSA implementation just sufficient for ssh client-side |
3 | * initialisation step |
4644b0ce |
4 | * |
5 | * Rewritten for more speed by Joris van Rantwijk, Jun 1999. |
374330e2 |
6 | */ |
7 | |
374330e2 |
8 | #include <stdio.h> |
9 | #include <stdlib.h> |
10 | #include <string.h> |
11 | |
374330e2 |
12 | #if defined TESTMODE || defined RSADEBUG |
13 | #ifndef DLVL |
14 | #define DLVL 10000 |
15 | #endif |
16 | #define debug(x) bndebug(#x,x) |
17 | static int level = 0; |
18 | static void bndebug(char *name, Bignum b) { |
19 | int i; |
20 | int w = 50-level-strlen(name)-5*b[0]; |
21 | if (level >= DLVL) |
22 | return; |
23 | if (w < 0) w = 0; |
24 | dprintf("%*s%s%*s", level, "", name, w, ""); |
25 | for (i=b[0]; i>0; i--) |
26 | dprintf(" %04x", b[i]); |
27 | dprintf("\n"); |
28 | } |
29 | #define dmsg(x) do {if(level<DLVL){dprintf("%*s",level,"");printf x;}} while(0) |
30 | #define enter(x) do { dmsg(x); level += 4; } while(0) |
31 | #define leave(x) do { level -= 4; dmsg(x); } while(0) |
32 | #else |
33 | #define debug(x) |
34 | #define dmsg(x) |
35 | #define enter(x) |
36 | #define leave(x) |
37 | #endif |
38 | |
e5574168 |
39 | #include "ssh.h" |
374330e2 |
40 | |
41 | int makekey(unsigned char *data, struct RSAKey *result, |
42 | unsigned char **keystr) { |
43 | unsigned char *p = data; |
44 | Bignum bn[2]; |
45 | int i, j; |
46 | int w, b; |
47 | |
48 | result->bits = 0; |
49 | for (i=0; i<4; i++) |
50 | result->bits = (result->bits << 8) + *p++; |
51 | |
52 | for (j=0; j<2; j++) { |
53 | |
54 | w = 0; |
55 | for (i=0; i<2; i++) |
56 | w = (w << 8) + *p++; |
57 | |
58 | result->bytes = b = (w+7)/8; /* bits -> bytes */ |
59 | w = (w+15)/16; /* bits -> words */ |
60 | |
61 | bn[j] = newbn(w); |
62 | |
63 | if (keystr) *keystr = p; /* point at key string, second time */ |
64 | |
65 | for (i=1; i<=w; i++) |
66 | bn[j][i] = 0; |
d9373729 |
67 | for (i=b; i-- ;) { |
374330e2 |
68 | unsigned char byte = *p++; |
d9373729 |
69 | if (i & 1) |
70 | bn[j][1+i/2] |= byte<<8; |
374330e2 |
71 | else |
d9373729 |
72 | bn[j][1+i/2] |= byte; |
374330e2 |
73 | } |
74 | |
75 | debug(bn[j]); |
76 | |
77 | } |
78 | |
79 | result->exponent = bn[0]; |
80 | result->modulus = bn[1]; |
81 | |
82 | return p - data; |
83 | } |
84 | |
85 | void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) { |
86 | Bignum b1, b2; |
87 | int w, i; |
88 | unsigned char *p; |
89 | |
90 | debug(key->exponent); |
91 | |
92 | memmove(data+key->bytes-length, data, length); |
93 | data[0] = 0; |
94 | data[1] = 2; |
95 | |
96 | for (i = 2; i < key->bytes-length-1; i++) { |
97 | do { |
98 | data[i] = random_byte(); |
99 | } while (data[i] == 0); |
100 | } |
101 | data[key->bytes-length-1] = 0; |
102 | |
103 | w = (key->bytes+1)/2; |
104 | |
105 | b1 = newbn(w); |
106 | b2 = newbn(w); |
107 | |
108 | p = data; |
109 | for (i=1; i<=w; i++) |
110 | b1[i] = 0; |
d9373729 |
111 | for (i=key->bytes; i-- ;) { |
374330e2 |
112 | unsigned char byte = *p++; |
d9373729 |
113 | if (i & 1) |
114 | b1[1+i/2] |= byte<<8; |
374330e2 |
115 | else |
d9373729 |
116 | b1[1+i/2] |= byte; |
374330e2 |
117 | } |
118 | |
119 | debug(b1); |
120 | |
121 | modpow(b1, key->exponent, key->modulus, b2); |
122 | |
123 | debug(b2); |
124 | |
125 | p = data; |
d9373729 |
126 | for (i=key->bytes; i-- ;) { |
374330e2 |
127 | unsigned char b; |
128 | if (i & 1) |
d9373729 |
129 | b = b2[1+i/2] >> 8; |
374330e2 |
130 | else |
d9373729 |
131 | b = b2[1+i/2] & 0xFF; |
374330e2 |
132 | *p++ = b; |
133 | } |
134 | |
135 | freebn(b1); |
136 | freebn(b2); |
137 | } |
138 | |
139 | int rsastr_len(struct RSAKey *key) { |
140 | Bignum md, ex; |
141 | |
142 | md = key->modulus; |
143 | ex = key->exponent; |
144 | return 4 * (ex[0]+md[0]) + 10; |
145 | } |
146 | |
147 | void rsastr_fmt(char *str, struct RSAKey *key) { |
148 | Bignum md, ex; |
149 | int len = 0, i; |
150 | |
151 | md = key->modulus; |
152 | ex = key->exponent; |
153 | |
154 | for (i=1; i<=ex[0]; i++) { |
155 | sprintf(str+len, "%04x", ex[i]); |
156 | len += strlen(str+len); |
157 | } |
158 | str[len++] = '/'; |
159 | for (i=1; i<=md[0]; i++) { |
160 | sprintf(str+len, "%04x", md[i]); |
161 | len += strlen(str+len); |
162 | } |
163 | str[len] = '\0'; |
164 | } |
165 | |
166 | #ifdef TESTMODE |
167 | |
168 | #ifndef NODDY |
169 | #define p1 10007 |
170 | #define p2 10069 |
171 | #define p3 10177 |
172 | #else |
173 | #define p1 3 |
174 | #define p2 7 |
175 | #define p3 13 |
176 | #endif |
177 | |
178 | unsigned short P1[2] = { 1, p1 }; |
179 | unsigned short P2[2] = { 1, p2 }; |
180 | unsigned short P3[2] = { 1, p3 }; |
181 | unsigned short bigmod[5] = { 4, 0, 0, 0, 32768U }; |
182 | unsigned short mod[5] = { 4, 0, 0, 0, 0 }; |
183 | unsigned short a[5] = { 4, 0, 0, 0, 0 }; |
184 | unsigned short b[5] = { 4, 0, 0, 0, 0 }; |
185 | unsigned short c[5] = { 4, 0, 0, 0, 0 }; |
186 | unsigned short One[2] = { 1, 1 }; |
187 | unsigned short Two[2] = { 1, 2 }; |
188 | |
189 | int main(void) { |
190 | modmult(P1, P2, bigmod, a); debug(a); |
191 | modmult(a, P3, bigmod, mod); debug(mod); |
192 | |
193 | sub(P1, One, a); debug(a); |
194 | sub(P2, One, b); debug(b); |
195 | modmult(a, b, bigmod, c); debug(c); |
196 | sub(P3, One, a); debug(a); |
197 | modmult(a, c, bigmod, b); debug(b); |
198 | |
199 | modpow(Two, b, mod, a); debug(a); |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | #endif |