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, |
7cca0d81 |
42 | unsigned char **keystr, int order) { |
374330e2 |
43 | unsigned char *p = data; |
7cca0d81 |
44 | int i; |
374330e2 |
45 | |
a52f067e |
46 | if (result) { |
47 | result->bits = 0; |
48 | for (i=0; i<4; i++) |
49 | result->bits = (result->bits << 8) + *p++; |
50 | } else |
51 | p += 4; |
374330e2 |
52 | |
7cca0d81 |
53 | /* |
54 | * order=0 means exponent then modulus (the keys sent by the |
55 | * server). order=1 means modulus then exponent (the keys |
56 | * stored in a keyfile). |
57 | */ |
374330e2 |
58 | |
7cca0d81 |
59 | if (order == 0) |
a52f067e |
60 | p += ssh1_read_bignum(p, result ? &result->exponent : NULL); |
61 | if (result) |
62 | result->bytes = (((p[0] << 8) + p[1]) + 7) / 8; |
7cca0d81 |
63 | if (keystr) *keystr = p+2; |
a52f067e |
64 | p += ssh1_read_bignum(p, result ? &result->modulus : NULL); |
7cca0d81 |
65 | if (order == 1) |
a52f067e |
66 | p += ssh1_read_bignum(p, result ? &result->exponent : NULL); |
374330e2 |
67 | |
68 | return p - data; |
69 | } |
70 | |
7cca0d81 |
71 | int makeprivate(unsigned char *data, struct RSAKey *result) { |
72 | return ssh1_read_bignum(data, &result->private_exponent); |
73 | } |
74 | |
374330e2 |
75 | void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) { |
76 | Bignum b1, b2; |
77 | int w, i; |
78 | unsigned char *p; |
79 | |
80 | debug(key->exponent); |
81 | |
82 | memmove(data+key->bytes-length, data, length); |
83 | data[0] = 0; |
84 | data[1] = 2; |
85 | |
86 | for (i = 2; i < key->bytes-length-1; i++) { |
87 | do { |
88 | data[i] = random_byte(); |
89 | } while (data[i] == 0); |
90 | } |
91 | data[key->bytes-length-1] = 0; |
92 | |
93 | w = (key->bytes+1)/2; |
94 | |
95 | b1 = newbn(w); |
96 | b2 = newbn(w); |
97 | |
98 | p = data; |
99 | for (i=1; i<=w; i++) |
100 | b1[i] = 0; |
d9373729 |
101 | for (i=key->bytes; i-- ;) { |
374330e2 |
102 | unsigned char byte = *p++; |
d9373729 |
103 | if (i & 1) |
104 | b1[1+i/2] |= byte<<8; |
374330e2 |
105 | else |
d9373729 |
106 | b1[1+i/2] |= byte; |
374330e2 |
107 | } |
108 | |
109 | debug(b1); |
110 | |
111 | modpow(b1, key->exponent, key->modulus, b2); |
112 | |
113 | debug(b2); |
114 | |
115 | p = data; |
d9373729 |
116 | for (i=key->bytes; i-- ;) { |
374330e2 |
117 | unsigned char b; |
118 | if (i & 1) |
d9373729 |
119 | b = b2[1+i/2] >> 8; |
374330e2 |
120 | else |
d9373729 |
121 | b = b2[1+i/2] & 0xFF; |
374330e2 |
122 | *p++ = b; |
123 | } |
124 | |
125 | freebn(b1); |
126 | freebn(b2); |
127 | } |
128 | |
7cca0d81 |
129 | Bignum rsadecrypt(Bignum input, struct RSAKey *key) { |
130 | Bignum ret; |
131 | ret = newbn(key->modulus[0]); |
132 | modpow(input, key->private_exponent, key->modulus, ret); |
133 | return ret; |
134 | } |
135 | |
374330e2 |
136 | int rsastr_len(struct RSAKey *key) { |
137 | Bignum md, ex; |
138 | |
139 | md = key->modulus; |
140 | ex = key->exponent; |
141 | return 4 * (ex[0]+md[0]) + 10; |
142 | } |
143 | |
144 | void rsastr_fmt(char *str, struct RSAKey *key) { |
145 | Bignum md, ex; |
146 | int len = 0, i; |
147 | |
148 | md = key->modulus; |
149 | ex = key->exponent; |
150 | |
151 | for (i=1; i<=ex[0]; i++) { |
152 | sprintf(str+len, "%04x", ex[i]); |
153 | len += strlen(str+len); |
154 | } |
155 | str[len++] = '/'; |
156 | for (i=1; i<=md[0]; i++) { |
157 | sprintf(str+len, "%04x", md[i]); |
158 | len += strlen(str+len); |
159 | } |
160 | str[len] = '\0'; |
161 | } |
162 | |
5c58ad2d |
163 | void freersakey(struct RSAKey *key) { |
164 | if (key->modulus) freebn(key->modulus); |
165 | if (key->exponent) freebn(key->exponent); |
166 | if (key->private_exponent) freebn(key->private_exponent); |
167 | if (key->comment) free(key->comment); |
168 | } |
169 | |
374330e2 |
170 | #ifdef TESTMODE |
171 | |
172 | #ifndef NODDY |
173 | #define p1 10007 |
174 | #define p2 10069 |
175 | #define p3 10177 |
176 | #else |
177 | #define p1 3 |
178 | #define p2 7 |
179 | #define p3 13 |
180 | #endif |
181 | |
182 | unsigned short P1[2] = { 1, p1 }; |
183 | unsigned short P2[2] = { 1, p2 }; |
184 | unsigned short P3[2] = { 1, p3 }; |
185 | unsigned short bigmod[5] = { 4, 0, 0, 0, 32768U }; |
186 | unsigned short mod[5] = { 4, 0, 0, 0, 0 }; |
187 | unsigned short a[5] = { 4, 0, 0, 0, 0 }; |
188 | unsigned short b[5] = { 4, 0, 0, 0, 0 }; |
189 | unsigned short c[5] = { 4, 0, 0, 0, 0 }; |
190 | unsigned short One[2] = { 1, 1 }; |
191 | unsigned short Two[2] = { 1, 2 }; |
192 | |
193 | int main(void) { |
194 | modmult(P1, P2, bigmod, a); debug(a); |
195 | modmult(a, P3, bigmod, mod); debug(mod); |
196 | |
197 | sub(P1, One, a); debug(a); |
198 | sub(P2, One, b); debug(b); |
199 | modmult(a, b, bigmod, c); debug(c); |
200 | sub(P3, One, a); debug(a); |
201 | modmult(a, c, bigmod, b); debug(b); |
202 | |
203 | modpow(Two, b, mod, a); debug(a); |
204 | |
205 | return 0; |
206 | } |
207 | |
208 | #endif |