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