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