Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / crypto / rsa.c
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ipxe/asn1.h>
28 #include <ipxe/crypto.h>
29 #include <ipxe/bigint.h>
30 #include <ipxe/random_nz.h>
31 #include <ipxe/md5.h>
32 #include <ipxe/sha1.h>
33 #include <ipxe/sha256.h>
34 #include <ipxe/rsa.h>
35
36 /** @file
37  *
38  * RSA public-key cryptography
39  *
40  * RSA is documented in RFC 3447.
41  */
42
43 /* Disambiguate the various error causes */
44 #define EACCES_VERIFY \
45         __einfo_error ( EINFO_EACCES_VERIFY )
46 #define EINFO_EACCES_VERIFY \
47         __einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )
48
49 /** "rsaEncryption" object identifier */
50 static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
51
52 /** "md5WithRSAEncryption" object identifier */
53 static uint8_t oid_md5_with_rsa_encryption[] =
54         { ASN1_OID_MD5WITHRSAENCRYPTION };
55
56 /** "sha1WithRSAEncryption" object identifier */
57 static uint8_t oid_sha1_with_rsa_encryption[] =
58         { ASN1_OID_SHA1WITHRSAENCRYPTION };
59
60 /** "sha256WithRSAEncryption" object identifier */
61 static uint8_t oid_sha256_with_rsa_encryption[] =
62         { ASN1_OID_SHA256WITHRSAENCRYPTION };
63
64 /** "rsaEncryption" OID-identified algorithm */
65 struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm = {
66         .name = "rsaEncryption",
67         .pubkey = &rsa_algorithm,
68         .digest = NULL,
69         .oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
70 };
71
72 /** "md5WithRSAEncryption" OID-identified algorithm */
73 struct asn1_algorithm md5_with_rsa_encryption_algorithm __asn1_algorithm = {
74         .name = "md5WithRSAEncryption",
75         .pubkey = &rsa_algorithm,
76         .digest = &md5_algorithm,
77         .oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
78 };
79
80 /** "sha1WithRSAEncryption" OID-identified algorithm */
81 struct asn1_algorithm sha1_with_rsa_encryption_algorithm __asn1_algorithm = {
82         .name = "sha1WithRSAEncryption",
83         .pubkey = &rsa_algorithm,
84         .digest = &sha1_algorithm,
85         .oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
86 };
87
88 /** "sha256WithRSAEncryption" OID-identified algorithm */
89 struct asn1_algorithm sha256_with_rsa_encryption_algorithm __asn1_algorithm = {
90         .name = "sha256WithRSAEncryption",
91         .pubkey = &rsa_algorithm,
92         .digest = &sha256_algorithm,
93         .oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
94 };
95
96 /** MD5 digestInfo prefix */
97 static const uint8_t rsa_md5_prefix_data[] =
98         { RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };
99
100 /** SHA-1 digestInfo prefix */
101 static const uint8_t rsa_sha1_prefix_data[] =
102         { RSA_DIGESTINFO_PREFIX ( SHA1_DIGEST_SIZE, ASN1_OID_SHA1 ) };
103
104 /** SHA-256 digestInfo prefix */
105 static const uint8_t rsa_sha256_prefix_data[] =
106         { RSA_DIGESTINFO_PREFIX ( SHA256_DIGEST_SIZE, ASN1_OID_SHA256 ) };
107
108 /** MD5 digestInfo prefix */
109 struct rsa_digestinfo_prefix rsa_md5_prefix __rsa_digestinfo_prefix = {
110         .digest = &md5_algorithm,
111         .data = rsa_md5_prefix_data,
112         .len = sizeof ( rsa_md5_prefix_data ),
113 };
114
115 /** SHA-1 digestInfo prefix */
116 struct rsa_digestinfo_prefix rsa_sha1_prefix __rsa_digestinfo_prefix = {
117         .digest = &sha1_algorithm,
118         .data = rsa_sha1_prefix_data,
119         .len = sizeof ( rsa_sha1_prefix_data ),
120 };
121
122 /** SHA-256 digestInfo prefix */
123 struct rsa_digestinfo_prefix rsa_sha256_prefix __rsa_digestinfo_prefix = {
124         .digest = &sha256_algorithm,
125         .data = rsa_sha256_prefix_data,
126         .len = sizeof ( rsa_sha256_prefix_data ),
127 };
128
129 /**
130  * Identify RSA prefix
131  *
132  * @v digest            Digest algorithm
133  * @ret prefix          RSA prefix, or NULL
134  */
135 static struct rsa_digestinfo_prefix *
136 rsa_find_prefix ( struct digest_algorithm *digest ) {
137         struct rsa_digestinfo_prefix *prefix;
138
139         for_each_table_entry ( prefix, RSA_DIGESTINFO_PREFIXES ) {
140                 if ( prefix->digest == digest )
141                         return prefix;
142         }
143         return NULL;
144 }
145
146 /**
147  * Free RSA dynamic storage
148  *
149  * @v context           RSA context
150  */
151 static void rsa_free ( struct rsa_context *context ) {
152
153         free ( context->dynamic );
154         context->dynamic = NULL;
155 }
156
157 /**
158  * Allocate RSA dynamic storage
159  *
160  * @v context           RSA context
161  * @v modulus_len       Modulus length
162  * @v exponent_len      Exponent length
163  * @ret rc              Return status code
164  */
165 static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
166                        size_t exponent_len ) {
167         unsigned int size = bigint_required_size ( modulus_len );
168         unsigned int exponent_size = bigint_required_size ( exponent_len );
169         bigint_t ( size ) *modulus;
170         bigint_t ( exponent_size ) *exponent;
171         size_t tmp_len = bigint_mod_exp_tmp_len ( modulus, exponent );
172         struct {
173                 bigint_t ( size ) modulus;
174                 bigint_t ( exponent_size ) exponent;
175                 bigint_t ( size ) input;
176                 bigint_t ( size ) output;
177                 uint8_t tmp[tmp_len];
178         } __attribute__ (( packed )) *dynamic;
179
180         /* Free any existing dynamic storage */
181         rsa_free ( context );
182
183         /* Allocate dynamic storage */
184         dynamic = malloc ( sizeof ( *dynamic ) );
185         if ( ! dynamic )
186                 return -ENOMEM;
187
188         /* Assign dynamic storage */
189         context->dynamic = dynamic;
190         context->modulus0 = &dynamic->modulus.element[0];
191         context->size = size;
192         context->max_len = modulus_len;
193         context->exponent0 = &dynamic->exponent.element[0];
194         context->exponent_size = exponent_size;
195         context->input0 = &dynamic->input.element[0];
196         context->output0 = &dynamic->output.element[0];
197         context->tmp = &dynamic->tmp;
198
199         return 0;
200 }
201
202 /**
203  * Parse RSA integer
204  *
205  * @v integer           Integer to fill in
206  * @v raw               ASN.1 cursor
207  * @ret rc              Return status code
208  */
209 static int rsa_parse_integer ( struct asn1_cursor *integer,
210                                const struct asn1_cursor *raw ) {
211
212         /* Enter integer */
213         memcpy ( integer, raw, sizeof ( *integer ) );
214         asn1_enter ( integer, ASN1_INTEGER );
215
216         /* Skip initial sign byte if applicable */
217         if ( ( integer->len > 1 ) &&
218              ( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
219                 integer->data++;
220                 integer->len--;
221         }
222
223         /* Fail if cursor or integer are invalid */
224         if ( ! integer->len )
225                 return -EINVAL;
226
227         return 0;
228 }
229
230 /**
231  * Parse RSA modulus and exponent
232  *
233  * @v modulus           Modulus to fill in
234  * @v exponent          Exponent to fill in
235  * @v raw               ASN.1 cursor
236  * @ret rc              Return status code
237  */
238 static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
239                                struct asn1_cursor *exponent,
240                                const struct asn1_cursor *raw ) {
241         struct asn1_bit_string bits;
242         struct asn1_cursor cursor;
243         int is_private;
244         int rc;
245
246         /* Enter subjectPublicKeyInfo/RSAPrivateKey */
247         memcpy ( &cursor, raw, sizeof ( cursor ) );
248         asn1_enter ( &cursor, ASN1_SEQUENCE );
249
250         /* Determine key format */
251         if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
252
253                 /* Private key */
254                 is_private = 1;
255
256                 /* Skip version */
257                 asn1_skip_any ( &cursor );
258
259         } else {
260
261                 /* Public key */
262                 is_private = 0;
263
264                 /* Skip algorithm */
265                 asn1_skip ( &cursor, ASN1_SEQUENCE );
266
267                 /* Enter subjectPublicKey */
268                 if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
269                         return rc;
270                 cursor.data = bits.data;
271                 cursor.len = bits.len;
272
273                 /* Enter RSAPublicKey */
274                 asn1_enter ( &cursor, ASN1_SEQUENCE );
275         }
276
277         /* Extract modulus */
278         if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
279                 return rc;
280         asn1_skip_any ( &cursor );
281
282         /* Skip public exponent, if applicable */
283         if ( is_private )
284                 asn1_skip ( &cursor, ASN1_INTEGER );
285
286         /* Extract publicExponent/privateExponent */
287         if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
288                 return rc;
289
290         return 0;
291 }
292
293 /**
294  * Initialise RSA cipher
295  *
296  * @v ctx               RSA context
297  * @v key               Key
298  * @v key_len           Length of key
299  * @ret rc              Return status code
300  */
301 static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
302         struct rsa_context *context = ctx;
303         struct asn1_cursor modulus;
304         struct asn1_cursor exponent;
305         struct asn1_cursor cursor;
306         int rc;
307
308         /* Initialise context */
309         memset ( context, 0, sizeof ( *context ) );
310
311         /* Initialise cursor */
312         cursor.data = key;
313         cursor.len = key_len;
314
315         /* Parse modulus and exponent */
316         if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, &cursor ) ) != 0 ){
317                 DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
318                 DBGC_HDA ( context, 0, cursor.data, cursor.len );
319                 goto err_parse;
320         }
321
322         DBGC ( context, "RSA %p modulus:\n", context );
323         DBGC_HDA ( context, 0, modulus.data, modulus.len );
324         DBGC ( context, "RSA %p exponent:\n", context );
325         DBGC_HDA ( context, 0, exponent.data, exponent.len );
326
327         /* Allocate dynamic storage */
328         if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
329                 goto err_alloc;
330
331         /* Construct big integers */
332         bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
333                       modulus.data, modulus.len );
334         bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
335                         context->exponent0 ), exponent.data, exponent.len );
336
337         return 0;
338
339         rsa_free ( context );
340  err_alloc:
341  err_parse:
342         return rc;
343 }
344
345 /**
346  * Calculate RSA maximum output length
347  *
348  * @v ctx               RSA context
349  * @ret max_len         Maximum output length
350  */
351 static size_t rsa_max_len ( void *ctx ) {
352         struct rsa_context *context = ctx;
353
354         return context->max_len;
355 }
356
357 /**
358  * Perform RSA cipher operation
359  *
360  * @v context           RSA context
361  * @v in                Input buffer
362  * @v out               Output buffer
363  */
364 static void rsa_cipher ( struct rsa_context *context,
365                          const void *in, void *out ) {
366         bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
367         bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
368         bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
369         bigint_t ( context->exponent_size ) *exponent =
370                 ( ( void * ) context->exponent0 );
371
372         /* Initialise big integer */
373         bigint_init ( input, in, context->max_len );
374
375         /* Perform modular exponentiation */
376         bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
377
378         /* Copy out result */
379         bigint_done ( output, out, context->max_len );
380 }
381
382 /**
383  * Encrypt using RSA
384  *
385  * @v ctx               RSA context
386  * @v plaintext         Plaintext
387  * @v plaintext_len     Length of plaintext
388  * @v ciphertext        Ciphertext
389  * @ret ciphertext_len  Length of ciphertext, or negative error
390  */
391 static int rsa_encrypt ( void *ctx, const void *plaintext,
392                          size_t plaintext_len, void *ciphertext ) {
393         struct rsa_context *context = ctx;
394         void *temp;
395         uint8_t *encoded;
396         size_t max_len = ( context->max_len - 11 );
397         size_t random_nz_len = ( max_len - plaintext_len + 8 );
398         int rc;
399
400         /* Sanity check */
401         if ( plaintext_len > max_len ) {
402                 DBGC ( context, "RSA %p plaintext too long (%zd bytes, max "
403                        "%zd)\n", context, plaintext_len, max_len );
404                 return -ERANGE;
405         }
406         DBGC ( context, "RSA %p encrypting:\n", context );
407         DBGC_HDA ( context, 0, plaintext, plaintext_len );
408
409         /* Construct encoded message (using the big integer output
410          * buffer as temporary storage)
411          */
412         temp = context->output0;
413         encoded = temp;
414         encoded[0] = 0x00;
415         encoded[1] = 0x02;
416         if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
417                 DBGC ( context, "RSA %p could not generate random data: %s\n",
418                        context, strerror ( rc ) );
419                 return rc;
420         }
421         encoded[ 2 + random_nz_len ] = 0x00;
422         memcpy ( &encoded[ context->max_len - plaintext_len ],
423                  plaintext, plaintext_len );
424
425         /* Encipher the encoded message */
426         rsa_cipher ( context, encoded, ciphertext );
427         DBGC ( context, "RSA %p encrypted:\n", context );
428         DBGC_HDA ( context, 0, ciphertext, context->max_len );
429
430         return context->max_len;
431 }
432
433 /**
434  * Decrypt using RSA
435  *
436  * @v ctx               RSA context
437  * @v ciphertext        Ciphertext
438  * @v ciphertext_len    Ciphertext length
439  * @v plaintext         Plaintext
440  * @ret plaintext_len   Plaintext length, or negative error
441  */
442 static int rsa_decrypt ( void *ctx, const void *ciphertext,
443                          size_t ciphertext_len, void *plaintext ) {
444         struct rsa_context *context = ctx;
445         void *temp;
446         uint8_t *encoded;
447         uint8_t *end;
448         uint8_t *zero;
449         uint8_t *start;
450         size_t plaintext_len;
451
452         /* Sanity check */
453         if ( ciphertext_len != context->max_len ) {
454                 DBGC ( context, "RSA %p ciphertext incorrect length (%zd "
455                        "bytes, should be %zd)\n",
456                        context, ciphertext_len, context->max_len );
457                 return -ERANGE;
458         }
459         DBGC ( context, "RSA %p decrypting:\n", context );
460         DBGC_HDA ( context, 0, ciphertext, ciphertext_len );
461
462         /* Decipher the message (using the big integer input buffer as
463          * temporary storage)
464          */
465         temp = context->input0;
466         encoded = temp;
467         rsa_cipher ( context, ciphertext, encoded );
468
469         /* Parse the message */
470         end = ( encoded + context->max_len );
471         if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) )
472                 goto invalid;
473         zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
474         if ( ! zero )
475                 goto invalid;
476         start = ( zero + 1 );
477         plaintext_len = ( end - start );
478
479         /* Copy out message */
480         memcpy ( plaintext, start, plaintext_len );
481         DBGC ( context, "RSA %p decrypted:\n", context );
482         DBGC_HDA ( context, 0, plaintext, plaintext_len );
483
484         return plaintext_len;
485
486  invalid:
487         DBGC ( context, "RSA %p invalid decrypted message:\n", context );
488         DBGC_HDA ( context, 0, encoded, context->max_len );
489         return -EINVAL;
490 }
491
492 /**
493  * Encode RSA digest
494  *
495  * @v context           RSA context
496  * @v digest            Digest algorithm
497  * @v value             Digest value
498  * @v encoded           Encoded digest
499  * @ret rc              Return status code
500  */
501 static int rsa_encode_digest ( struct rsa_context *context,
502                                struct digest_algorithm *digest,
503                                const void *value, void *encoded ) {
504         struct rsa_digestinfo_prefix *prefix;
505         size_t digest_len = digest->digestsize;
506         uint8_t *temp = encoded;
507         size_t digestinfo_len;
508         size_t max_len;
509         size_t pad_len;
510
511         /* Identify prefix */
512         prefix = rsa_find_prefix ( digest );
513         if ( ! prefix ) {
514                 DBGC ( context, "RSA %p has no prefix for %s\n",
515                        context, digest->name );
516                 return -ENOTSUP;
517         }
518         digestinfo_len = ( prefix->len + digest_len );
519
520         /* Sanity check */
521         max_len = ( context->max_len - 11 );
522         if ( digestinfo_len > max_len ) {
523                 DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, max"
524                        "%zd)\n",
525                        context, digest->name, digestinfo_len, max_len );
526                 return -ERANGE;
527         }
528         DBGC ( context, "RSA %p encoding %s digest:\n",
529                context, digest->name );
530         DBGC_HDA ( context, 0, value, digest_len );
531
532         /* Construct encoded message */
533         *(temp++) = 0x00;
534         *(temp++) = 0x01;
535         pad_len = ( max_len - digestinfo_len + 8 );
536         memset ( temp, 0xff, pad_len );
537         temp += pad_len;
538         *(temp++) = 0x00;
539         memcpy ( temp, prefix->data, prefix->len );
540         temp += prefix->len;
541         memcpy ( temp, value, digest_len );
542         temp += digest_len;
543         assert ( temp == ( encoded + context->max_len ) );
544         DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
545         DBGC_HDA ( context, 0, encoded, context->max_len );
546
547         return 0;
548 }
549
550 /**
551  * Sign digest value using RSA
552  *
553  * @v ctx               RSA context
554  * @v digest            Digest algorithm
555  * @v value             Digest value
556  * @v signature         Signature
557  * @ret signature_len   Signature length, or negative error
558  */
559 static int rsa_sign ( void *ctx, struct digest_algorithm *digest,
560                       const void *value, void *signature ) {
561         struct rsa_context *context = ctx;
562         void *temp;
563         int rc;
564
565         DBGC ( context, "RSA %p signing %s digest:\n", context, digest->name );
566         DBGC_HDA ( context, 0, value, digest->digestsize );
567
568         /* Encode digest (using the big integer output buffer as
569          * temporary storage)
570          */
571         temp = context->output0;
572         if ( ( rc = rsa_encode_digest ( context, digest, value, temp ) ) != 0 )
573                 return rc;
574
575         /* Encipher the encoded digest */
576         rsa_cipher ( context, temp, signature );
577         DBGC ( context, "RSA %p signed %s digest:\n", context, digest->name );
578         DBGC_HDA ( context, 0, signature, context->max_len );
579
580         return context->max_len;
581 }
582
583 /**
584  * Verify signed digest value using RSA
585  *
586  * @v ctx               RSA context
587  * @v digest            Digest algorithm
588  * @v value             Digest value
589  * @v signature         Signature
590  * @v signature_len     Signature length
591  * @ret rc              Return status code
592  */
593 static int rsa_verify ( void *ctx, struct digest_algorithm *digest,
594                         const void *value, const void *signature,
595                         size_t signature_len ) {
596         struct rsa_context *context = ctx;
597         void *temp;
598         void *expected;
599         void *actual;
600         int rc;
601
602         /* Sanity check */
603         if ( signature_len != context->max_len ) {
604                 DBGC ( context, "RSA %p signature incorrect length (%zd "
605                        "bytes, should be %zd)\n",
606                        context, signature_len, context->max_len );
607                 return -ERANGE;
608         }
609         DBGC ( context, "RSA %p verifying %s digest:\n",
610                context, digest->name );
611         DBGC_HDA ( context, 0, value, digest->digestsize );
612         DBGC_HDA ( context, 0, signature, signature_len );
613
614         /* Decipher the signature (using the big integer input buffer
615          * as temporary storage)
616          */
617         temp = context->input0;
618         expected = temp;
619         rsa_cipher ( context, signature, expected );
620         DBGC ( context, "RSA %p deciphered signature:\n", context );
621         DBGC_HDA ( context, 0, expected, context->max_len );
622
623         /* Encode digest (using the big integer output buffer as
624          * temporary storage)
625          */
626         temp = context->output0;
627         actual = temp;
628         if ( ( rc = rsa_encode_digest ( context, digest, value, actual ) ) !=0 )
629                 return rc;
630
631         /* Verify the signature */
632         if ( memcmp ( actual, expected, context->max_len ) != 0 ) {
633                 DBGC ( context, "RSA %p signature verification failed\n",
634                        context );
635                 return -EACCES_VERIFY;
636         }
637
638         DBGC ( context, "RSA %p signature verified successfully\n", context );
639         return 0;
640 }
641
642 /**
643  * Finalise RSA cipher
644  *
645  * @v ctx               RSA context
646  */
647 static void rsa_final ( void *ctx ) {
648         struct rsa_context *context = ctx;
649
650         rsa_free ( context );
651 }
652
653 /**
654  * Check for matching RSA public/private key pair
655  *
656  * @v private_key       Private key
657  * @v private_key_len   Private key length
658  * @v public_key        Public key
659  * @v public_key_len    Public key length
660  * @ret rc              Return status code
661  */
662 static int rsa_match ( const void *private_key, size_t private_key_len,
663                        const void *public_key, size_t public_key_len ) {
664         struct asn1_cursor private_modulus;
665         struct asn1_cursor private_exponent;
666         struct asn1_cursor private_cursor;
667         struct asn1_cursor public_modulus;
668         struct asn1_cursor public_exponent;
669         struct asn1_cursor public_cursor;
670         int rc;
671
672         /* Initialise cursors */
673         private_cursor.data = private_key;
674         private_cursor.len = private_key_len;
675         public_cursor.data = public_key;
676         public_cursor.len = public_key_len;
677
678         /* Parse moduli and exponents */
679         if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
680                                         &private_cursor ) ) != 0 )
681                 return rc;
682         if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
683                                         &public_cursor ) ) != 0 )
684                 return rc;
685
686         /* Compare moduli */
687         if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
688                 return -ENOTTY;
689
690         return 0;
691 }
692
693 /** RSA public-key algorithm */
694 struct pubkey_algorithm rsa_algorithm = {
695         .name           = "rsa",
696         .ctxsize        = sizeof ( struct rsa_context ),
697         .init           = rsa_init,
698         .max_len        = rsa_max_len,
699         .encrypt        = rsa_encrypt,
700         .decrypt        = rsa_decrypt,
701         .sign           = rsa_sign,
702         .verify         = rsa_verify,
703         .final          = rsa_final,
704         .match          = rsa_match,
705 };