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 | |
46 | result->bits = 0; |
47 | for (i=0; i<4; i++) |
48 | result->bits = (result->bits << 8) + *p++; |
49 | |
7cca0d81 |
50 | /* |
51 | * order=0 means exponent then modulus (the keys sent by the |
52 | * server). order=1 means modulus then exponent (the keys |
53 | * stored in a keyfile). |
54 | */ |
374330e2 |
55 | |
7cca0d81 |
56 | if (order == 0) |
57 | p += ssh1_read_bignum(p, &result->exponent); |
58 | result->bytes = (((p[0] << 8) + p[1]) + 7) / 8; |
59 | if (keystr) *keystr = p+2; |
60 | p += ssh1_read_bignum(p, &result->modulus); |
61 | if (order == 1) |
62 | p += ssh1_read_bignum(p, &result->exponent); |
374330e2 |
63 | |
64 | return p - data; |
65 | } |
66 | |
7cca0d81 |
67 | int makeprivate(unsigned char *data, struct RSAKey *result) { |
68 | return ssh1_read_bignum(data, &result->private_exponent); |
69 | } |
70 | |
374330e2 |
71 | void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) { |
72 | Bignum b1, b2; |
73 | int w, i; |
74 | unsigned char *p; |
75 | |
76 | debug(key->exponent); |
77 | |
78 | memmove(data+key->bytes-length, data, length); |
79 | data[0] = 0; |
80 | data[1] = 2; |
81 | |
82 | for (i = 2; i < key->bytes-length-1; i++) { |
83 | do { |
84 | data[i] = random_byte(); |
85 | } while (data[i] == 0); |
86 | } |
87 | data[key->bytes-length-1] = 0; |
88 | |
89 | w = (key->bytes+1)/2; |
90 | |
91 | b1 = newbn(w); |
92 | b2 = newbn(w); |
93 | |
94 | p = data; |
95 | for (i=1; i<=w; i++) |
96 | b1[i] = 0; |
d9373729 |
97 | for (i=key->bytes; i-- ;) { |
374330e2 |
98 | unsigned char byte = *p++; |
d9373729 |
99 | if (i & 1) |
100 | b1[1+i/2] |= byte<<8; |
374330e2 |
101 | else |
d9373729 |
102 | b1[1+i/2] |= byte; |
374330e2 |
103 | } |
104 | |
105 | debug(b1); |
106 | |
107 | modpow(b1, key->exponent, key->modulus, b2); |
108 | |
109 | debug(b2); |
110 | |
111 | p = data; |
d9373729 |
112 | for (i=key->bytes; i-- ;) { |
374330e2 |
113 | unsigned char b; |
114 | if (i & 1) |
d9373729 |
115 | b = b2[1+i/2] >> 8; |
374330e2 |
116 | else |
d9373729 |
117 | b = b2[1+i/2] & 0xFF; |
374330e2 |
118 | *p++ = b; |
119 | } |
120 | |
121 | freebn(b1); |
122 | freebn(b2); |
123 | } |
124 | |
7cca0d81 |
125 | Bignum rsadecrypt(Bignum input, struct RSAKey *key) { |
126 | Bignum ret; |
127 | ret = newbn(key->modulus[0]); |
128 | modpow(input, key->private_exponent, key->modulus, ret); |
129 | return ret; |
130 | } |
131 | |
374330e2 |
132 | int rsastr_len(struct RSAKey *key) { |
133 | Bignum md, ex; |
134 | |
135 | md = key->modulus; |
136 | ex = key->exponent; |
137 | return 4 * (ex[0]+md[0]) + 10; |
138 | } |
139 | |
140 | void rsastr_fmt(char *str, struct RSAKey *key) { |
141 | Bignum md, ex; |
142 | int len = 0, i; |
143 | |
144 | md = key->modulus; |
145 | ex = key->exponent; |
146 | |
147 | for (i=1; i<=ex[0]; i++) { |
148 | sprintf(str+len, "%04x", ex[i]); |
149 | len += strlen(str+len); |
150 | } |
151 | str[len++] = '/'; |
152 | for (i=1; i<=md[0]; i++) { |
153 | sprintf(str+len, "%04x", md[i]); |
154 | len += strlen(str+len); |
155 | } |
156 | str[len] = '\0'; |
157 | } |
158 | |
5c58ad2d |
159 | void freersakey(struct RSAKey *key) { |
160 | if (key->modulus) freebn(key->modulus); |
161 | if (key->exponent) freebn(key->exponent); |
162 | if (key->private_exponent) freebn(key->private_exponent); |
163 | if (key->comment) free(key->comment); |
164 | } |
165 | |
374330e2 |
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 |