iPXE
rsa.c
Go to the documentation of this file.
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 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <stdarg.h>
30#include <string.h>
31#include <errno.h>
32#include <ipxe/asn1.h>
33#include <ipxe/crypto.h>
34#include <ipxe/bigint.h>
35#include <ipxe/random_nz.h>
36#include <ipxe/rsa.h>
37
38/** @file
39 *
40 * RSA public-key cryptography
41 *
42 * RSA is documented in RFC 3447.
43 */
44
45/* Disambiguate the various error causes */
46#define EACCES_VERIFY \
47 __einfo_error ( EINFO_EACCES_VERIFY )
48#define EINFO_EACCES_VERIFY \
49 __einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )
50
51/** An RSA context */
53 /** Allocated memory */
54 void *dynamic;
55 /** Modulus */
57 /** Modulus size */
58 unsigned int size;
59 /** Modulus length */
60 size_t max_len;
61 /** Exponent */
63 /** Exponent size */
64 unsigned int exponent_size;
65 /** Input buffer */
67 /** Output buffer */
69 /** Temporary working space for modular exponentiation */
70 void *tmp;
71};
72
73/**
74 * Identify RSA prefix
75 *
76 * @v digest Digest algorithm
77 * @ret prefix RSA prefix, or NULL
78 */
79static struct rsa_digestinfo_prefix *
82
84 if ( prefix->digest == digest )
85 return prefix;
86 }
87 return NULL;
88}
89
90/**
91 * Free RSA dynamic storage
92 *
93 * @v context RSA context
94 */
95static inline void rsa_free ( struct rsa_context *context ) {
96
97 free ( context->dynamic );
98}
99
100/**
101 * Allocate RSA dynamic storage
102 *
103 * @v context RSA context
104 * @v modulus_len Modulus length
105 * @v exponent_len Exponent length
106 * @ret rc Return status code
107 */
108static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
109 size_t exponent_len ) {
110 unsigned int size = bigint_required_size ( modulus_len );
111 unsigned int exponent_size = bigint_required_size ( exponent_len );
112 bigint_t ( size ) *modulus;
113 size_t tmp_len = bigint_mod_exp_tmp_len ( modulus );
114 struct {
115 bigint_t ( size ) modulus;
116 bigint_t ( exponent_size ) exponent;
117 bigint_t ( size ) input;
118 bigint_t ( size ) output;
119 uint8_t tmp[tmp_len];
120 } __attribute__ (( packed )) *dynamic;
121
122 /* Allocate dynamic storage */
123 dynamic = malloc ( sizeof ( *dynamic ) );
124 if ( ! dynamic )
125 return -ENOMEM;
126
127 /* Assign dynamic storage */
128 context->dynamic = dynamic;
129 context->modulus0 = &dynamic->modulus.element[0];
130 context->size = size;
131 context->max_len = modulus_len;
132 context->exponent0 = &dynamic->exponent.element[0];
133 context->exponent_size = exponent_size;
134 context->input0 = &dynamic->input.element[0];
135 context->output0 = &dynamic->output.element[0];
136 context->tmp = &dynamic->tmp;
137
138 return 0;
139}
140
141/**
142 * Parse RSA modulus and exponent
143 *
144 * @v modulus Modulus to fill in
145 * @v exponent Exponent to fill in
146 * @v raw ASN.1 cursor
147 * @ret rc Return status code
148 */
149static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
150 struct asn1_cursor *exponent,
151 const struct asn1_cursor *raw ) {
152 struct asn1_cursor cursor;
153 int is_private;
154 int rc;
155
156 /* Enter subjectPublicKeyInfo/privateKeyInfo/RSAPrivateKey */
157 memcpy ( &cursor, raw, sizeof ( cursor ) );
158 asn1_enter ( &cursor, ASN1_SEQUENCE );
159
160 /* Determine key format */
161 if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
162
163 /* Private key */
164 is_private = 1;
165
166 /* Skip version */
167 asn1_skip_any ( &cursor );
168
169 /* Enter privateKey, if present */
170 if ( asn1_check_algorithm ( &cursor, &rsa_encryption_algorithm,
171 NULL ) == 0 ) {
172
173 /* Skip privateKeyAlgorithm */
174 asn1_skip_any ( &cursor );
175
176 /* Enter privateKey */
177 asn1_enter ( &cursor, ASN1_OCTET_STRING );
178
179 /* Enter RSAPrivateKey */
180 asn1_enter ( &cursor, ASN1_SEQUENCE );
181
182 /* Skip version */
183 asn1_skip ( &cursor, ASN1_INTEGER );
184 }
185
186 } else {
187
188 /* Public key */
189 is_private = 0;
190
191 /* Skip algorithm */
192 asn1_skip ( &cursor, ASN1_SEQUENCE );
193
194 /* Enter subjectPublicKey */
195 asn1_enter_bits ( &cursor, NULL );
196
197 /* Enter RSAPublicKey */
198 asn1_enter ( &cursor, ASN1_SEQUENCE );
199 }
200
201 /* Extract modulus */
202 memcpy ( modulus, &cursor, sizeof ( *modulus ) );
203 if ( ( rc = asn1_enter_unsigned ( modulus ) ) != 0 )
204 return rc;
205 asn1_skip_any ( &cursor );
206
207 /* Skip public exponent, if applicable */
208 if ( is_private )
209 asn1_skip ( &cursor, ASN1_INTEGER );
210
211 /* Extract publicExponent/privateExponent */
212 memcpy ( exponent, &cursor, sizeof ( *exponent ) );
213 if ( ( rc = asn1_enter_unsigned ( exponent ) ) != 0 )
214 return rc;
215
216 return 0;
217}
218
219/**
220 * Initialise RSA cipher
221 *
222 * @v context RSA context
223 * @v key Key
224 * @ret rc Return status code
225 */
226static int rsa_init ( struct rsa_context *context,
227 const struct asn1_cursor *key ) {
228 struct asn1_cursor modulus;
229 struct asn1_cursor exponent;
230 int rc;
231
232 /* Initialise context */
233 memset ( context, 0, sizeof ( *context ) );
234
235 /* Parse modulus and exponent */
236 if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, key ) ) != 0 ){
237 DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
238 DBGC_HDA ( context, 0, key->data, key->len );
239 goto err_parse;
240 }
241
242 DBGC ( context, "RSA %p modulus:\n", context );
243 DBGC_HDA ( context, 0, modulus.data, modulus.len );
244 DBGC ( context, "RSA %p exponent:\n", context );
245 DBGC_HDA ( context, 0, exponent.data, exponent.len );
246
247 /* Allocate dynamic storage */
248 if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
249 goto err_alloc;
250
251 /* Construct big integers */
252 bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
253 modulus.data, modulus.len );
254 bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
255 context->exponent0 ), exponent.data, exponent.len );
256
257 return 0;
258
259 rsa_free ( context );
260 err_alloc:
261 err_parse:
262 return rc;
263}
264
265/**
266 * Perform RSA cipher operation
267 *
268 * @v context RSA context
269 * @v in Input buffer
270 * @v out Output buffer
271 */
272static void rsa_cipher ( struct rsa_context *context,
273 const void *in, void *out ) {
274 bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
275 bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
276 bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
277 bigint_t ( context->exponent_size ) *exponent =
278 ( ( void * ) context->exponent0 );
279
280 /* Initialise big integer */
281 bigint_init ( input, in, context->max_len );
282
283 /* Perform modular exponentiation */
284 bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
285
286 /* Copy out result */
287 bigint_done ( output, out, context->max_len );
288}
289
290/**
291 * Encrypt using RSA
292 *
293 * @v key Key
294 * @v plaintext Plaintext
295 * @v ciphertext Ciphertext
296 * @ret ciphertext_len Length of ciphertext, or negative error
297 */
298static int rsa_encrypt ( const struct asn1_cursor *key,
299 const struct asn1_cursor *plaintext,
300 struct asn1_builder *ciphertext ) {
301 struct rsa_context context;
302 void *temp;
303 uint8_t *encoded;
304 size_t max_len;
305 size_t random_nz_len;
306 int rc;
307
308 DBGC ( &context, "RSA %p encrypting:\n", &context );
309 DBGC_HDA ( &context, 0, plaintext->data, plaintext->len );
310
311 /* Initialise context */
312 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
313 goto err_init;
314
315 /* Calculate lengths */
316 max_len = ( context.max_len - 11 );
317 random_nz_len = ( max_len - plaintext->len + 8 );
318
319 /* Sanity check */
320 if ( plaintext->len > max_len ) {
321 DBGC ( &context, "RSA %p plaintext too long (%zd bytes, max "
322 "%zd)\n", &context, plaintext->len, max_len );
323 rc = -ERANGE;
324 goto err_sanity;
325 }
326
327 /* Construct encoded message (using the big integer output
328 * buffer as temporary storage)
329 */
330 temp = context.output0;
331 encoded = temp;
332 encoded[0] = 0x00;
333 encoded[1] = 0x02;
334 if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
335 DBGC ( &context, "RSA %p could not generate random data: %s\n",
336 &context, strerror ( rc ) );
337 goto err_random;
338 }
339 encoded[ 2 + random_nz_len ] = 0x00;
340 memcpy ( &encoded[ context.max_len - plaintext->len ],
341 plaintext->data, plaintext->len );
342
343 /* Create space for ciphertext */
344 if ( ( rc = asn1_grow ( ciphertext, context.max_len ) ) != 0 )
345 goto err_grow;
346
347 /* Encipher the encoded message */
348 rsa_cipher ( &context, encoded, ciphertext->data );
349 DBGC ( &context, "RSA %p encrypted:\n", &context );
350 DBGC_HDA ( &context, 0, ciphertext->data, context.max_len );
351
352 /* Free context */
353 rsa_free ( &context );
354
355 return 0;
356
357 err_grow:
358 err_random:
359 err_sanity:
360 rsa_free ( &context );
361 err_init:
362 return rc;
363}
364
365/**
366 * Decrypt using RSA
367 *
368 * @v key Key
369 * @v ciphertext Ciphertext
370 * @v plaintext Plaintext
371 * @ret rc Return status code
372 */
373static int rsa_decrypt ( const struct asn1_cursor *key,
374 const struct asn1_cursor *ciphertext,
375 struct asn1_builder *plaintext ) {
376 struct rsa_context context;
377 void *temp;
378 uint8_t *encoded;
379 uint8_t *end;
380 uint8_t *zero;
381 uint8_t *start;
382 size_t len;
383 int rc;
384
385 DBGC ( &context, "RSA %p decrypting:\n", &context );
386 DBGC_HDA ( &context, 0, ciphertext->data, ciphertext->len );
387
388 /* Initialise context */
389 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
390 goto err_init;
391
392 /* Sanity check */
393 if ( ciphertext->len != context.max_len ) {
394 DBGC ( &context, "RSA %p ciphertext incorrect length (%zd "
395 "bytes, should be %zd)\n",
396 &context, ciphertext->len, context.max_len );
397 rc = -ERANGE;
398 goto err_sanity;
399 }
400
401 /* Decipher the message (using the big integer input buffer as
402 * temporary storage)
403 */
404 temp = context.input0;
405 encoded = temp;
406 rsa_cipher ( &context, ciphertext->data, encoded );
407
408 /* Parse the message */
409 end = ( encoded + context.max_len );
410 if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) ) {
411 rc = -EINVAL;
412 goto err_invalid;
413 }
414 zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
415 if ( ! zero ) {
416 DBGC ( &context, "RSA %p invalid decrypted message:\n",
417 &context );
418 DBGC_HDA ( &context, 0, encoded, context.max_len );
419 rc = -EINVAL;
420 goto err_invalid;
421 }
422 start = ( zero + 1 );
423 len = ( end - start );
424
425 /* Create space for plaintext */
426 if ( ( rc = asn1_grow ( plaintext, len ) ) != 0 )
427 goto err_grow;
428
429 /* Copy out message */
430 memcpy ( plaintext->data, start, len );
431 DBGC ( &context, "RSA %p decrypted:\n", &context );
432 DBGC_HDA ( &context, 0, plaintext->data, len );
433
434 /* Free context */
435 rsa_free ( &context );
436
437 return 0;
438
439 err_grow:
440 err_invalid:
441 err_sanity:
442 rsa_free ( &context );
443 err_init:
444 return rc;
445}
446
447/**
448 * Encode RSA digest
449 *
450 * @v context RSA context
451 * @v digest Digest algorithm
452 * @v value Digest value
453 * @v encoded Encoded digest
454 * @ret rc Return status code
455 */
456static int rsa_encode_digest ( struct rsa_context *context,
457 struct digest_algorithm *digest,
458 const void *value, void *encoded ) {
460 size_t digest_len = digest->digestsize;
461 uint8_t *temp = encoded;
462 size_t digestinfo_len;
463 size_t max_len;
464 size_t pad_len;
465
466 /* Identify prefix */
468 if ( ! prefix ) {
469 DBGC ( context, "RSA %p has no prefix for %s\n",
470 context, digest->name );
471 return -ENOTSUP;
472 }
473 digestinfo_len = ( prefix->len + digest_len );
474
475 /* Sanity check */
476 max_len = ( context->max_len - 11 );
477 if ( digestinfo_len > max_len ) {
478 DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, "
479 "max %zd)\n", context, digest->name, digestinfo_len,
480 max_len );
481 return -ERANGE;
482 }
483 DBGC ( context, "RSA %p encoding %s digest:\n",
484 context, digest->name );
485 DBGC_HDA ( context, 0, value, digest_len );
486
487 /* Construct encoded message */
488 *(temp++) = 0x00;
489 *(temp++) = 0x01;
490 pad_len = ( max_len - digestinfo_len + 8 );
491 memset ( temp, 0xff, pad_len );
492 temp += pad_len;
493 *(temp++) = 0x00;
494 memcpy ( temp, prefix->data, prefix->len );
495 temp += prefix->len;
496 memcpy ( temp, value, digest_len );
497 temp += digest_len;
498 assert ( temp == ( encoded + context->max_len ) );
499 DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
500 DBGC_HDA ( context, 0, encoded, context->max_len );
501
502 return 0;
503}
504
505/**
506 * Sign digest value using RSA
507 *
508 * @v key Key
509 * @v digest Digest algorithm
510 * @v value Digest value
511 * @v signature Signature
512 * @ret rc Return status code
513 */
514static int rsa_sign ( const struct asn1_cursor *key,
515 struct digest_algorithm *digest, const void *value,
516 struct asn1_builder *signature ) {
517 struct rsa_context context;
518 int rc;
519
520 DBGC ( &context, "RSA %p signing %s digest:\n",
521 &context, digest->name );
522 DBGC_HDA ( &context, 0, value, digest->digestsize );
523
524 /* Initialise context */
525 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
526 goto err_init;
527
528 /* Create space for encoded digest and signature */
529 if ( ( rc = asn1_grow ( signature, context.max_len ) ) != 0 )
530 goto err_grow;
531
532 /* Encode digest */
533 if ( ( rc = rsa_encode_digest ( &context, digest, value,
534 signature->data ) ) != 0 )
535 goto err_encode;
536
537 /* Encipher the encoded digest */
538 rsa_cipher ( &context, signature->data, signature->data );
539 DBGC ( &context, "RSA %p signed %s digest:\n", &context, digest->name );
540 DBGC_HDA ( &context, 0, signature->data, signature->len );
541
542 /* Free context */
543 rsa_free ( &context );
544
545 return 0;
546
547 err_encode:
548 err_grow:
549 rsa_free ( &context );
550 err_init:
551 return rc;
552}
553
554/**
555 * Verify signed digest value using RSA
556 *
557 * @v key Key
558 * @v digest Digest algorithm
559 * @v value Digest value
560 * @v signature Signature
561 * @ret rc Return status code
562 */
563static int rsa_verify ( const struct asn1_cursor *key,
564 struct digest_algorithm *digest, const void *value,
565 const struct asn1_cursor *signature ) {
566 struct rsa_context context;
567 void *temp;
568 void *expected;
569 void *actual;
570 int rc;
571
572 DBGC ( &context, "RSA %p verifying %s digest:\n",
573 &context, digest->name );
574 DBGC_HDA ( &context, 0, value, digest->digestsize );
575 DBGC_HDA ( &context, 0, signature->data, signature->len );
576
577 /* Initialise context */
578 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
579 goto err_init;
580
581 /* Sanity check */
582 if ( signature->len != context.max_len ) {
583 DBGC ( &context, "RSA %p signature incorrect length (%zd "
584 "bytes, should be %zd)\n",
585 &context, signature->len, context.max_len );
586 rc = -ERANGE;
587 goto err_sanity;
588 }
589
590 /* Decipher the signature (using the big integer input buffer
591 * as temporary storage)
592 */
593 temp = context.input0;
594 expected = temp;
595 rsa_cipher ( &context, signature->data, expected );
596 DBGC ( &context, "RSA %p deciphered signature:\n", &context );
597 DBGC_HDA ( &context, 0, expected, context.max_len );
598
599 /* Encode digest (using the big integer output buffer as
600 * temporary storage)
601 */
602 temp = context.output0;
603 actual = temp;
604 if ( ( rc = rsa_encode_digest ( &context, digest, value,
605 actual ) ) != 0 )
606 goto err_encode;
607
608 /* Verify the signature */
609 if ( memcmp ( actual, expected, context.max_len ) != 0 ) {
610 DBGC ( &context, "RSA %p signature verification failed\n",
611 &context );
612 rc = -EACCES_VERIFY;
613 goto err_verify;
614 }
615
616 /* Free context */
617 rsa_free ( &context );
618
619 DBGC ( &context, "RSA %p signature verified successfully\n", &context );
620 return 0;
621
622 err_verify:
623 err_encode:
624 err_sanity:
625 rsa_free ( &context );
626 err_init:
627 return rc;
628}
629
630/**
631 * Check for matching RSA public/private key pair
632 *
633 * @v private_key Private key
634 * @v public_key Public key
635 * @ret rc Return status code
636 */
637static int rsa_match ( const struct asn1_cursor *private_key,
638 const struct asn1_cursor *public_key ) {
639 struct asn1_cursor private_modulus;
640 struct asn1_cursor private_exponent;
641 struct asn1_cursor public_modulus;
642 struct asn1_cursor public_exponent;
643 int rc;
644
645 /* Parse moduli and exponents */
646 if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
647 private_key ) ) != 0 )
648 return rc;
649 if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
650 public_key ) ) != 0 )
651 return rc;
652
653 /* Compare moduli */
654 if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
655 return -ENOTTY;
656
657 return 0;
658}
659
660/** RSA public-key algorithm */
662 .name = "rsa",
663 .encrypt = rsa_encrypt,
664 .decrypt = rsa_decrypt,
665 .sign = rsa_sign,
666 .verify = rsa_verify,
667 .match = rsa_match,
668};
669
670/* Drag in objects via rsa_algorithm */
672
673/* Drag in crypto configuration */
674REQUIRE_OBJECT ( config_crypto );
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
__be32 raw[7]
Definition CIB_PRM.h:0
__be32 in[4]
Definition CIB_PRM.h:7
u8 signature
CPU signature.
Definition CIB_PRM.h:7
__be32 out[4]
Definition CIB_PRM.h:8
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned char uint8_t
Definition stdint.h:10
long pad_len
Definition bigint.h:31
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:16
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition asn1.c:369
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
int asn1_check_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm *expected, struct asn1_cursor *params)
Check ASN.1 OID-identified algorithm.
Definition asn1.c:705
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition asn1.c:916
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition asn1.c:231
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition asn1.c:311
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
ASN.1 encoding.
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:479
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
ring len
Length.
Definition dwmac.h:226
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
uint32_t start
Starting offset.
Definition netvsc.h:1
uint16_t size
Buffer size.
Definition dwmac.h:3
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define REQUIRE_OBJECT(object)
Require an object.
Definition compiler.h:202
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ERANGE
Result too large.
Definition errno.h:640
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define REQUIRING_SYMBOL(symbol)
Specify the file's requiring symbol.
Definition compiler.h:140
#define __attribute__(x)
Definition compiler.h:10
Big integer support.
#define bigint_mod_exp(base, modulus, exponent, result, tmp)
Perform modular exponentiation of big integers.
Definition bigint.h:347
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition bigint.h:361
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:31
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
Cryptographic API.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
unsigned long tmp
Definition linux_pci.h:65
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
uint32_t end
Ending offset.
Definition netvsc.h:7
int get_random_nz(void *data, size_t len)
Get random non-zero bytes.
Definition random_nz.c:63
HMAC_DRBG algorithm.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define EACCES_VERIFY
Definition rsa.c:46
static int rsa_verify(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Verify signed digest value using RSA.
Definition rsa.c:563
static int rsa_match(const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching RSA public/private key pair.
Definition rsa.c:637
static int rsa_encode_digest(struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
Encode RSA digest.
Definition rsa.c:456
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition rsa.c:95
static struct rsa_digestinfo_prefix * rsa_find_prefix(struct digest_algorithm *digest)
Identify RSA prefix.
Definition rsa.c:80
static int rsa_parse_mod_exp(struct asn1_cursor *modulus, struct asn1_cursor *exponent, const struct asn1_cursor *raw)
Parse RSA modulus and exponent.
Definition rsa.c:149
struct pubkey_algorithm rsa_algorithm
RSA public-key algorithm.
Definition rsa.c:661
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition rsa.c:226
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition rsa.c:272
static int rsa_alloc(struct rsa_context *context, size_t modulus_len, size_t exponent_len)
Allocate RSA dynamic storage.
Definition rsa.c:108
static int rsa_sign(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Sign digest value using RSA.
Definition rsa.c:514
static int rsa_decrypt(const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
Decrypt using RSA.
Definition rsa.c:373
static int rsa_encrypt(const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
Encrypt using RSA.
Definition rsa.c:298
RSA public-key cryptography.
#define RSA_DIGESTINFO_PREFIXES
RSA digestInfo prefix table.
Definition rsa.h:53
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
void * memchr(const void *src, int character, size_t len)
Find character within a memory region.
Definition string.c:136
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
An ASN.1 object builder.
Definition asn1.h:29
void * data
Data.
Definition asn1.h:36
An ASN.1 object cursor.
Definition asn1.h:21
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27
const char * name
Algorithm name.
Definition crypto.h:21
A private key.
Definition privkey.h:17
A public key algorithm.
Definition crypto.h:122
An RSA context.
Definition rsa.c:52
bigint_element_t * exponent0
Exponent.
Definition rsa.c:62
bigint_element_t * input0
Input buffer.
Definition rsa.c:66
void * dynamic
Allocated memory.
Definition rsa.c:54
void * tmp
Temporary working space for modular exponentiation.
Definition rsa.c:70
bigint_element_t * modulus0
Modulus.
Definition rsa.c:56
unsigned int exponent_size
Exponent size.
Definition rsa.c:64
bigint_element_t * output0
Output buffer.
Definition rsa.c:68
size_t max_len
Modulus length.
Definition rsa.c:60
unsigned int size
Modulus size.
Definition rsa.c:58
An RSA digestInfo prefix.
Definition rsa.h:43
struct digest_algorithm * digest
Digest algorithm.
Definition rsa.h:45
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
char prefix[4]
Definition vmconsole.c:53