1 /* Software-based Trusted Platform Module (TPM) Emulator
2 * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3 *
4 * This module is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
8 *
9 * This module is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * $Id: rsa.c 364 2010-02-11 10:24:45Z mast $
15 */
16
17 #include "rsa.h"
18 #include "sha1.h"
19 #include "tpm/tpm_commands.h"
20
rsa_public(tpm_rsa_public_key_t * key,const uint8_t * in,size_t in_len,uint8_t * out)21 static int rsa_public(tpm_rsa_public_key_t *key,
22 const uint8_t *in, size_t in_len, uint8_t *out)
23 {
24 size_t t;
25 tpm_bn_t p, c;
26
27 tpm_bn_init2(p, key->size);
28 tpm_bn_init2(c, key->size);
29 tpm_bn_import(p, in_len, 1, in);
30 /* c = p ^ d mod n */
31 tpm_bn_powm(c, p, key->e, key->n);
32 t = tpm_bn_bitsize(c);
33 if (t > key->size) {
34 tpm_bn_clear(p);
35 tpm_bn_clear(c);
36 return -1;
37 }
38 t = (key->size - t) >> 3;
39 memset(out, 0, t);
40 tpm_bn_export(&out[t], &t, 1, c);
41 tpm_bn_clear(p);
42 tpm_bn_clear(c);
43 return 0;
44 }
45
rsa_private(tpm_rsa_private_key_t * key,const uint8_t * in,size_t in_len,uint8_t * out)46 static int rsa_private(tpm_rsa_private_key_t *key,
47 const uint8_t *in, size_t in_len, uint8_t *out)
48 {
49 size_t t;
50 tpm_bn_t p, c, m1, m2, h;
51
52 tpm_bn_init2(p, key->size);
53 tpm_bn_init2(c, key->size);
54 tpm_bn_import(p, in_len, 1, in);
55
56 if (!key->p || !key->q || !key->u) {
57 /* c = p ^ d mod n */
58 tpm_bn_powm(c, p, key->d, key->n);
59 } else {
60 tpm_bn_init2(m1, key->size / 2);
61 tpm_bn_init2(m2, key->size / 2);
62 tpm_bn_init2(h, key->size);
63 /* m1 = p ^ (d mod (p-1)) mod p */
64 tpm_bn_sub_ui(h, key->p, 1);
65 tpm_bn_mod(h, key->d, h);
66 tpm_bn_powm(m1, p, h, key->p);
67 /* m2 = p ^ (d mod (q-1)) mod q */
68 tpm_bn_sub_ui(h, key->q, 1);
69 tpm_bn_mod(h, key->d, h);
70 tpm_bn_powm(m2, p, h, key->q);
71 /* h = u * ( m2 - m1 ) mod q */
72 tpm_bn_sub(h, m2, m1);
73 if (tpm_bn_sgn(h) < 0) tpm_bn_add(h, h, key->q);
74 tpm_bn_mul(h, key->u, h);
75 tpm_bn_mod(h, h, key->q);
76 /* c = m1 + h * p */
77 tpm_bn_mul(h, h, key->p);
78 tpm_bn_add(c, m1, h);
79 tpm_bn_clear(m1);
80 tpm_bn_clear(m2);
81 tpm_bn_clear(h);
82 }
83 t = tpm_bn_bitsize(c);
84 if (t > key->size) {
85 tpm_bn_clear(p);
86 tpm_bn_clear(c);
87 return -1;
88 }
89 t = (key->size - t) >> 3;
90 memset(out, 0, t);
91 tpm_bn_export(&out[t], &t, 1, c);
92 tpm_bn_clear(p);
93 tpm_bn_clear(c);
94 return 0;
95 }
96
rsa_test_key(tpm_rsa_private_key_t * key)97 static int rsa_test_key(tpm_rsa_private_key_t *key)
98 {
99 tpm_bn_t a, b, t;
100 int res = 0;
101
102 tpm_bn_init2(a, key->size);
103 tpm_bn_init2(b, key->size);
104 tpm_bn_init2(t, key->size);
105 tpm_bn_set_ui(t, 0xdeadbeef);
106 tpm_bn_powm(a, t, key->e, key->n);
107 tpm_bn_powm(b, a, key->d, key->n);
108 if (tpm_bn_cmp(t, b) != 0) res = -1;
109 tpm_bn_powm(a, t, key->d, key->n);
110 tpm_bn_powm(b, a, key->e, key->n);
111 if (tpm_bn_cmp(t, b) != 0) res = -1;
112 tpm_bn_clear(a);
113 tpm_bn_clear(b);
114 tpm_bn_clear(t);
115 return res;
116 }
117
tpm_rsa_import_key(tpm_rsa_private_key_t * key,int endian,const uint8_t * n,size_t n_len,const uint8_t * e,size_t e_len,const uint8_t * p,const uint8_t * q)118 int tpm_rsa_import_key(tpm_rsa_private_key_t *key, int endian,
119 const uint8_t *n, size_t n_len,
120 const uint8_t *e, size_t e_len,
121 const uint8_t *p, const uint8_t *q)
122 {
123 tpm_bn_t t1, t2, phi;
124 if (n == NULL || n_len == 0 || (p == NULL && q == NULL)) return -1;
125 /* init key */
126 key->size = n_len << 3;
127 if (e == NULL || e_len == 0) {
128 tpm_bn_init_set_ui(key->e, 65537);
129 } else {
130 tpm_bn_init2(key->e, e_len << 3);
131 tpm_bn_import(key->e, e_len, endian, e);
132 }
133 tpm_bn_init2(key->n, key->size);
134 tpm_bn_init2(key->p, key->size / 2);
135 tpm_bn_init2(key->q, key->size / 2);
136 tpm_bn_init2(key->d, key->size);
137 tpm_bn_init2(key->u, key->size / 2);
138 tpm_bn_init2(t1, key->size / 2);
139 tpm_bn_init2(t2, key->size / 2);
140 tpm_bn_init2(phi, key->size);
141 /* import values */
142 tpm_bn_import(key->n, n_len, endian, n);
143 if (p != NULL) tpm_bn_import(key->p, n_len / 2, endian, p);
144 if (q != NULL) tpm_bn_import(key->q, n_len / 2, endian, q);
145 if (p == NULL) tpm_bn_tdiv_q(key->p, key->n, key->q);
146 if (q == NULL) tpm_bn_tdiv_q(key->q, key->n, key->p);
147 /* p shall be smaller than q */
148 if (tpm_bn_cmp(key->p, key->q) > 0) tpm_bn_swap(key->p, key->q);
149 /* calculate missing values */
150 tpm_bn_sub_ui(t1, key->p, 1);
151 tpm_bn_sub_ui(t2, key->q, 1);
152 tpm_bn_mul(phi, t1, t2);
153 tpm_bn_invert(key->d, key->e, phi);
154 tpm_bn_invert(key->u, key->p, key->q);
155 /* release helper variables */
156 tpm_bn_clear(t1);
157 tpm_bn_clear(t2);
158 tpm_bn_clear(phi);
159 /* test key */
160 if (rsa_test_key(key) != 0) {
161 tpm_rsa_release_private_key(key);
162 return -1;
163 }
164 return 0;
165 }
166
tpm_rsa_copy_key(tpm_rsa_private_key_t * dst,tpm_rsa_private_key_t * src)167 void tpm_rsa_copy_key(tpm_rsa_private_key_t *dst, tpm_rsa_private_key_t *src)
168 {
169 tpm_bn_init_set(dst->n, src->n);
170 tpm_bn_init_set(dst->e, src->e);
171 tpm_bn_init_set(dst->d, src->d);
172 tpm_bn_init_set(dst->p, src->p);
173 tpm_bn_init_set(dst->q, src->q);
174 tpm_bn_init_set(dst->u, src->u);
175 dst->size = src->size;
176 }
177
tpm_rsa_import_public_key(tpm_rsa_public_key_t * key,int endian,const uint8_t * n,size_t n_len,const uint8_t * e,size_t e_len)178 int tpm_rsa_import_public_key(tpm_rsa_public_key_t *key, int endian,
179 const uint8_t *n, size_t n_len,
180 const uint8_t *e, size_t e_len)
181 {
182 if (n == NULL || n_len == 0) return -1;
183 /* init key */
184 key->size = n_len << 3;
185 if (e == NULL || e_len == 0) {
186 tpm_bn_init_set_ui(key->e, 65537);
187 } else {
188 tpm_bn_init2(key->e, e_len << 3);
189 tpm_bn_import(key->e, e_len, endian, e);
190 }
191 tpm_bn_init2(key->n, key->size);
192 /* import values */
193 tpm_bn_import(key->n, n_len, endian, n);
194 return 0;
195 }
196
rsa_tpm_bn_random(tpm_bn_t a,size_t nbits)197 static void rsa_tpm_bn_random(tpm_bn_t a, size_t nbits)
198 {
199 size_t size = nbits >> 3;
200 uint8_t buf[size];
201 tpm_get_random_bytes(buf, size);
202 tpm_bn_import(a, size, 1, buf);
203 }
204
tpm_rsa_generate_key(tpm_rsa_private_key_t * key,uint16_t key_size)205 int tpm_rsa_generate_key(tpm_rsa_private_key_t *key, uint16_t key_size)
206 {
207 tpm_bn_t e, p, q, n, t1, t2, phi, d, u;
208
209 /* bit_size must be a multiply of eight */
210 while (key_size & 0x07) key_size++;
211 /* we use e = 65537 */
212 tpm_bn_init_set_ui(e, 65537);
213 tpm_bn_init2(p, key_size / 2);
214 tpm_bn_init2(q, key_size / 2);
215 tpm_bn_init2(n, key_size);
216 tpm_bn_init2(t1, key_size / 2);
217 tpm_bn_init2(t2, key_size / 2);
218 tpm_bn_init2(phi, key_size);
219 tpm_bn_init2(d, key_size);
220 tpm_bn_init2(u, key_size / 2);
221 do {
222 /* get prime p */
223 rsa_tpm_bn_random(p, key_size / 2);
224 tpm_bn_setbit(p, 0);
225 tpm_bn_setbit(p, key_size / 2 - 1);
226 tpm_bn_setbit(p, key_size / 2 - 2);
227 tpm_bn_nextprime(p, p);
228 tpm_bn_sub_ui(t1, p, 1);
229 tpm_bn_gcd(phi, e, t1);
230 if (tpm_bn_cmp_ui(phi, 1) != 0) continue;
231 /* get prime q */
232 rsa_tpm_bn_random(q, key_size / 2);
233 tpm_bn_setbit(q, 0);
234 tpm_bn_setbit(q, key_size / 2 - 1);
235 tpm_bn_setbit(q, key_size / 2 - 2);
236 tpm_bn_nextprime(q, q);
237 tpm_bn_sub_ui(t2, q, 1);
238 tpm_bn_gcd(phi, e, t1);
239 if (tpm_bn_cmp_ui(phi, 1) != 0) continue;
240 /* p shall be smaller than q */
241 if (tpm_bn_cmp(p, q) > 0) tpm_bn_swap(p, q);
242 /* calculate the modulus */
243 tpm_bn_mul(n, p, q);
244 } while (tpm_bn_bitsize(n) != key_size);
245 /* calculate Euler totient: phi = (p-1)(q-1) */
246 tpm_bn_mul(phi, t1, t2);
247 /* calculate the secret key d = e^(-1) mod phi */
248 tpm_bn_invert(d, e, phi);
249 /* calculate the inverse of p and q (used for chinese remainder theorem) */
250 tpm_bn_invert(u, p, q);
251 /* setup private key */
252 tpm_bn_init_set(key->n, n);
253 tpm_bn_init_set(key->e, e);
254 tpm_bn_init_set(key->p, p);
255 tpm_bn_init_set(key->q, q);
256 tpm_bn_init_set(key->d, d);
257 tpm_bn_init_set(key->u, u);
258 key->size = key_size;
259 /* release helper variables */
260 tpm_bn_clear(e);
261 tpm_bn_clear(p);
262 tpm_bn_clear(q);
263 tpm_bn_clear(n);
264 tpm_bn_clear(t1);
265 tpm_bn_clear(t2);
266 tpm_bn_clear(phi);
267 tpm_bn_clear(d);
268 tpm_bn_clear(u);
269 /* test key */
270 if (rsa_test_key(key) != 0) {
271 tpm_rsa_release_private_key(key);
272 return -1;
273 }
274 return 0;
275 }
276
tpm_rsa_release_private_key(tpm_rsa_private_key_t * key)277 void tpm_rsa_release_private_key(tpm_rsa_private_key_t *key)
278 {
279 tpm_bn_clear(key->n);
280 tpm_bn_clear(key->e);
281 tpm_bn_clear(key->p);
282 tpm_bn_clear(key->q);
283 tpm_bn_clear(key->d);
284 tpm_bn_clear(key->u);
285 memset(key, 0, sizeof(*key));
286 }
287
tpm_rsa_release_public_key(tpm_rsa_public_key_t * key)288 void tpm_rsa_release_public_key(tpm_rsa_public_key_t *key)
289 {
290 tpm_bn_clear(key->n);
291 tpm_bn_clear(key->e);
292 memset(key, 0, sizeof(*key));
293 }
294
tpm_rsa_export_modulus(tpm_rsa_private_key_t * key,uint8_t * modulus,size_t * length)295 void tpm_rsa_export_modulus(tpm_rsa_private_key_t *key,
296 uint8_t *modulus, size_t *length)
297 {
298 tpm_bn_export(modulus, length, 1, key->n);
299 }
300
tpm_rsa_export_exponent(tpm_rsa_private_key_t * key,uint8_t * exponent,size_t * length)301 void tpm_rsa_export_exponent(tpm_rsa_private_key_t *key,
302 uint8_t *exponent, size_t *length)
303 {
304 tpm_bn_export(exponent, length, 1, key->e);
305 }
306
tpm_rsa_export_prime1(tpm_rsa_private_key_t * key,uint8_t * prime,size_t * length)307 void tpm_rsa_export_prime1(tpm_rsa_private_key_t *key,
308 uint8_t *prime, size_t *length)
309 {
310 tpm_bn_export(prime, length, 1, key->p);
311 }
312
tpm_rsa_export_prime2(tpm_rsa_private_key_t * key,uint8_t * prime,size_t * length)313 void tpm_rsa_export_prime2(tpm_rsa_private_key_t *key,
314 uint8_t *prime, size_t *length)
315 {
316 tpm_bn_export(prime, length, 1, key->q);
317 }
318
tpm_rsa_export_public_modulus(tpm_rsa_public_key_t * key,uint8_t * modulus,size_t * length)319 void tpm_rsa_export_public_modulus(tpm_rsa_public_key_t *key,
320 uint8_t *modulus, size_t *length)
321 {
322 tpm_bn_export(modulus, length, 1, key->n);
323 }
324
tpm_rsa_export_public_exponent(tpm_rsa_public_key_t * key,uint8_t * exponent,size_t * length)325 void tpm_rsa_export_public_exponent(tpm_rsa_public_key_t *key,
326 uint8_t *exponent, size_t *length)
327 {
328 tpm_bn_export(exponent, length, 1, key->e);
329 }
330
tpm_rsa_modulus_length(tpm_rsa_private_key_t * key)331 size_t tpm_rsa_modulus_length(tpm_rsa_private_key_t *key)
332 {
333 return (tpm_bn_bitsize(key->n) + 7) >> 3;
334 }
335
tpm_rsa_exponent_length(tpm_rsa_private_key_t * key)336 size_t tpm_rsa_exponent_length(tpm_rsa_private_key_t *key)
337 {
338 return (tpm_bn_bitsize(key->e) + 7) >> 3;
339 }
340
tpm_rsa_prime1_length(tpm_rsa_private_key_t * key)341 size_t tpm_rsa_prime1_length(tpm_rsa_private_key_t *key)
342 {
343 return (tpm_bn_bitsize(key->p) + 7) >> 3;
344 }
345
tpm_rsa_prime2_length(tpm_rsa_private_key_t * key)346 size_t tpm_rsa_prime2_length(tpm_rsa_private_key_t *key)
347 {
348 return (tpm_bn_bitsize(key->q) + 7) >> 3;
349 }
350
tpm_rsa_public_modulus_length(tpm_rsa_public_key_t * key)351 size_t tpm_rsa_public_modulus_length(tpm_rsa_public_key_t *key)
352 {
353 return (tpm_bn_bitsize(key->n) + 7) >> 3;
354 }
355
tpm_rsa_public_exponent_length(tpm_rsa_public_key_t * key)356 size_t tpm_rsa_public_exponent_length(tpm_rsa_public_key_t *key)
357 {
358 return (tpm_bn_bitsize(key->e) + 7) >> 3;
359 }
360
tpm_rsa_mask_generation(const uint8_t * seed,size_t seed_len,uint8_t * data,size_t data_len)361 void tpm_rsa_mask_generation(const uint8_t *seed, size_t seed_len,
362 uint8_t *data, size_t data_len)
363 {
364 tpm_sha1_ctx_t ctx;
365 uint8_t mask[SHA1_DIGEST_LENGTH];
366 uint32_t i, len, counter = 0;
367
368 while (data_len > 0) {
369 tpm_sha1_init(&ctx);
370 tpm_sha1_update(&ctx, seed, seed_len);
371 tpm_sha1_update_be32(&ctx, counter);
372 tpm_sha1_final(&ctx, mask);
373 counter++;
374 len = (data_len < SHA1_DIGEST_LENGTH) ? data_len : SHA1_DIGEST_LENGTH;
375 for (i = 0; i < len; i++) *data++ ^= mask[i];
376 data_len -= len;
377 }
378 }
379
encode_message(int type,const uint8_t * data,size_t data_len,uint8_t * msg,size_t msg_len)380 static int encode_message(int type, const uint8_t *data, size_t data_len,
381 uint8_t *msg, size_t msg_len)
382 {
383 size_t i;
384 tpm_sha1_ctx_t ctx;
385
386 /* encode message according to type */
387 switch (type) {
388 case RSA_SSA_PKCS1_SHA1:
389 /* EM = 0x00||0x01||0xff-pad||0x00||SHA-1 DER header||SHA-1 digest */
390 if (msg_len < 35 + 11) return -1;
391 msg[0] = 0x00; msg[1] = 0x01;
392 memset(&msg[2], 0xff, msg_len - 38);
393 msg[msg_len - 36] = 0x00;
394 memcpy(&msg[msg_len - 35], "\x30\x21\x30\x09\x06\x05\x2b"
395 "\x0e\x03\x02\x1a\x05\x00\x04\x14", 15);
396 tpm_sha1_init(&ctx);
397 tpm_sha1_update(&ctx, data, data_len);
398 tpm_sha1_final(&ctx, &msg[msg_len - 20]);
399 break;
400 case RSA_SSA_PKCS1_SHA1_RAW:
401 /* EM = 0x00||0x01||0xff-pad||0x00||SHA-1 DER header||SHA-1 digest */
402 if (msg_len < 35 + 11 || data_len != 20) return -1;
403 msg[0] = 0x00; msg[1] = 0x01;
404 memset(&msg[2], 0xff, msg_len - 38);
405 msg[msg_len - 36] = 0x00;
406 memcpy(&msg[msg_len - 35], "\x30\x21\x30\x09\x06\x05\x2b"
407 "\x0e\x03\x02\x1a\x05\x00\x04\x14", 15);
408 memcpy(&msg[msg_len - 20], data, data_len);
409 break;
410 case RSA_SSA_PKCS1_DER:
411 /* EM = 0x00||0x01||0xff-pad||0x00||DER encoded data */
412 if (msg_len < data_len + 11) return -1;
413 msg[0] = 0x00; msg[1] = 0x01;
414 memset(&msg[2], 0xff, msg_len - data_len - 3);
415 msg[msg_len - data_len - 1] = 0x00;
416 memcpy(&msg[msg_len - data_len], data, data_len);
417 break;
418 case RSA_ES_PKCSV15:
419 /* EM = 0x00||0x02||nonzero random-pad||0x00||data */
420 if (msg_len < data_len + 11) return -1;
421 msg[0] = 0x00; msg[1] = 0x02;
422 tpm_get_random_bytes(&msg[2], msg_len - data_len - 3);
423 for (i = 2; i < msg_len - data_len; i++)
424 while (!msg[i]) tpm_get_random_bytes(&msg[i], 1);
425 msg[msg_len - data_len - 1] = 0x00;
426 memcpy(&msg[msg_len - data_len], data, data_len);
427 break;
428 case RSA_ES_OAEP_SHA1:
429 /* DB = SHA-1("TCPA")||0x00-pad||0x01||data
430 seed = random value of size SHA1_DIGEST_LENGTH
431 masked-seed = seed xor MFG(seed, seed_len)
432 masked-DB = DB xor MFG(seed, DB_len)
433 EM = 0x00||masked-seed||masked-DB */
434 if (msg_len < data_len + 2 * SHA1_DIGEST_LENGTH + 2) return -1;
435 msg[0] = 0x00;
436 tpm_get_random_bytes(&msg[1], SHA1_DIGEST_LENGTH);
437 tpm_sha1_init(&ctx);
438 tpm_sha1_update(&ctx, (uint8_t*)"TCPA", 4);
439 tpm_sha1_final(&ctx, &msg[1 + SHA1_DIGEST_LENGTH]);
440 memset(&msg[1 + 2 * SHA1_DIGEST_LENGTH], 0x00,
441 msg_len - data_len - 2 * SHA1_DIGEST_LENGTH - 2);
442 msg[msg_len - data_len - 1] = 0x01;
443 memcpy(&msg[msg_len - data_len], data, data_len);
444 tpm_rsa_mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
445 &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
446 tpm_rsa_mask_generation(&msg[1 + SHA1_DIGEST_LENGTH],
447 msg_len - SHA1_DIGEST_LENGTH - 1, &msg[1], SHA1_DIGEST_LENGTH);
448 break;
449 case RSA_ES_PLAIN:
450 /* EM = data */
451 if (msg_len != data_len) return -1;
452 if (msg != data) memcpy(msg, data, data_len);
453 break;
454 default:
455 /* unsupported encoding method */
456 return -1;
457 }
458 return 0;
459 }
460
decode_message(int type,uint8_t * msg,size_t msg_len,uint8_t * data,size_t * data_len)461 static int decode_message(int type, uint8_t *msg, size_t msg_len,
462 uint8_t *data, size_t *data_len)
463 {
464 size_t i;
465 tpm_sha1_ctx_t ctx;
466
467 /* decode message according to type */
468 switch (type) {
469 case RSA_ES_PKCSV15:
470 /* EM = 0x00||0x02||nonzero random-pad||0x00||data */
471 if (msg_len < 11) return -1;
472 if (msg[0] != 0x00 || msg[1] != 0x02) return -1;
473 for (i = 2; i < msg_len && msg[i]; i++);
474 if (i < 10 || i >= msg_len) return -1;
475 *data_len = msg_len - i - 1;
476 memmove(data, &msg[i + 1], *data_len);
477 break;
478 case RSA_ES_OAEP_SHA1:
479 /* DB = SHA-1("TCPA")||0x00-pad||0x01||data
480 seed = random value of size SHA1_DIGEST_LENGTH
481 masked-seed = seed xor MFG(seed, seed_len)
482 masked-DB = DB xor MFG(seed, DB_len)
483 EM = 0x00||masked-seed||masked-DB */
484 if (msg_len < 2 + 2 * SHA1_DIGEST_LENGTH) return -1;
485 if (msg[0] != 0x00) return -1;
486 tpm_rsa_mask_generation(&msg[1 + SHA1_DIGEST_LENGTH],
487 msg_len - SHA1_DIGEST_LENGTH - 1, &msg[1], SHA1_DIGEST_LENGTH);
488 tpm_rsa_mask_generation(&msg[1], SHA1_DIGEST_LENGTH,
489 &msg[1 + SHA1_DIGEST_LENGTH], msg_len - SHA1_DIGEST_LENGTH - 1);
490 tpm_sha1_init(&ctx);
491 tpm_sha1_update(&ctx, (uint8_t*)"TCPA", 4);
492 tpm_sha1_final(&ctx, &msg[1]);
493 if (memcmp(&msg[1], &msg[1 + SHA1_DIGEST_LENGTH],
494 SHA1_DIGEST_LENGTH) != 0) return -1;
495 for (i = 1 + 2 * SHA1_DIGEST_LENGTH; i < msg_len && !msg[i]; i++);
496 if (i >= msg_len || msg[i] != 0x01) return -1;
497 *data_len = msg_len - i - 1;
498 memmove(data, &msg[i + 1], *data_len);
499 break;
500 case RSA_ES_PLAIN:
501 /* EM = data */
502 *data_len = msg_len;
503 if (msg != data) memcpy(msg, data, msg_len);
504 break;
505 default:
506 /* unsupported encoding method */
507 return -1;
508 }
509 return 0;
510 }
511
tpm_rsa_sign(tpm_rsa_private_key_t * key,int type,const uint8_t * data,size_t data_len,uint8_t * sig)512 int tpm_rsa_sign(tpm_rsa_private_key_t *key, int type,
513 const uint8_t *data, size_t data_len, uint8_t *sig)
514 {
515 size_t sig_len = key->size >> 3;
516
517 /* encode message */
518 if (encode_message(type, data, data_len, sig, sig_len) != 0) return -1;
519 /* sign encoded message */
520 if (rsa_private(key, sig, sig_len, sig) != 0) return -1;
521 return 0;
522 }
523
tpm_rsa_verify(tpm_rsa_public_key_t * key,int type,const uint8_t * data,size_t data_len,uint8_t * sig)524 int tpm_rsa_verify(tpm_rsa_public_key_t *key, int type,
525 const uint8_t *data, size_t data_len, uint8_t *sig)
526 {
527 size_t sig_len = key->size >> 3;
528 uint8_t msg_a[sig_len];
529 uint8_t msg_b[sig_len];
530
531 /* encode message */
532 if (encode_message(type, data, data_len, msg_a, sig_len) != 0) return -1;
533 /* decrypt signature */
534 if (rsa_public(key, sig, sig_len, msg_b) != 0) return -1;
535 /* compare messages */
536 return (memcmp(msg_a, msg_b, sig_len) == 0) ? 0 : 1;
537 }
538
tpm_rsa_decrypt(tpm_rsa_private_key_t * key,int type,const uint8_t * in,size_t in_len,uint8_t * out,size_t * out_len)539 int tpm_rsa_decrypt(tpm_rsa_private_key_t *key, int type,
540 const uint8_t *in, size_t in_len,
541 uint8_t *out, size_t *out_len)
542 {
543 *out_len = key->size >> 3;
544 if (in_len != *out_len || in_len < 11) return -1;
545 /* decrypt message */
546 if (rsa_private(key, in, in_len, out) != 0) return -1;
547 /* decode message */
548 if (decode_message(type, out, *out_len, out, out_len) != 0) return -1;
549 return 0;
550 }
551
tpm_rsa_encrypt(tpm_rsa_public_key_t * key,int type,const uint8_t * in,size_t in_len,uint8_t * out,size_t * out_len)552 int tpm_rsa_encrypt(tpm_rsa_public_key_t *key, int type,
553 const uint8_t *in, size_t in_len,
554 uint8_t *out, size_t *out_len)
555 {
556 *out_len = key->size >> 3;
557 /* encode message */
558 if (encode_message(type, in, in_len, out, *out_len) != 0) return -1;
559 /* encrypt encoded message */
560 if (rsa_public(key, out, *out_len, out) != 0) return -1;
561 return 0;
562 }
563
564