iPXE
Data Structures | Macros | Functions | Variables
rsa.c File Reference

RSA public-key cryptography. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <ipxe/asn1.h>
#include <ipxe/crypto.h>
#include <ipxe/bigint.h>
#include <ipxe/random_nz.h>
#include <ipxe/rsa.h>

Go to the source code of this file.

Data Structures

struct  rsa_context
 An RSA context. More...
 

Macros

#define EACCES_VERIFY   __einfo_error ( EINFO_EACCES_VERIFY )
 
#define EINFO_EACCES_VERIFY   __einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static struct rsa_digestinfo_prefixrsa_find_prefix (struct digest_algorithm *digest)
 Identify RSA prefix. More...
 
static void rsa_free (struct rsa_context *context)
 Free RSA dynamic storage. More...
 
static int rsa_alloc (struct rsa_context *context, size_t modulus_len, size_t exponent_len)
 Allocate RSA dynamic storage. More...
 
static int rsa_parse_integer (struct asn1_cursor *integer, const struct asn1_cursor *raw)
 Parse RSA integer. More...
 
static int rsa_parse_mod_exp (struct asn1_cursor *modulus, struct asn1_cursor *exponent, const struct asn1_cursor *raw)
 Parse RSA modulus and exponent. More...
 
static int rsa_init (struct rsa_context *context, const struct asn1_cursor *key)
 Initialise RSA cipher. More...
 
static size_t rsa_max_len (const struct asn1_cursor *key)
 Calculate RSA maximum output length. More...
 
static void rsa_cipher (struct rsa_context *context, const void *in, void *out)
 Perform RSA cipher operation. More...
 
static int rsa_encrypt (const struct asn1_cursor *key, const void *plaintext, size_t plaintext_len, void *ciphertext)
 Encrypt using RSA. More...
 
static int rsa_decrypt (const struct asn1_cursor *key, const void *ciphertext, size_t ciphertext_len, void *plaintext)
 Decrypt using RSA. More...
 
static int rsa_encode_digest (struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
 Encode RSA digest. More...
 
static int rsa_sign (const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, void *signature)
 Sign digest value using RSA. More...
 
static int rsa_verify (const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
 Verify signed digest value using RSA. More...
 
static int rsa_match (const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
 Check for matching RSA public/private key pair. More...
 
 REQUIRING_SYMBOL (rsa_algorithm)
 
 REQUIRE_OBJECT (config_crypto)
 

Variables

struct pubkey_algorithm rsa_algorithm
 RSA public-key algorithm. More...
 

Detailed Description

RSA public-key cryptography.

RSA is documented in RFC 3447.

Definition in file rsa.c.

Macro Definition Documentation

◆ EACCES_VERIFY

#define EACCES_VERIFY   __einfo_error ( EINFO_EACCES_VERIFY )

Definition at line 45 of file rsa.c.

◆ EINFO_EACCES_VERIFY

#define EINFO_EACCES_VERIFY   __einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )

Definition at line 47 of file rsa.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ rsa_find_prefix()

static struct rsa_digestinfo_prefix* rsa_find_prefix ( struct digest_algorithm digest)
static

Identify RSA prefix.

Parameters
digestDigest algorithm
Return values
prefixRSA prefix, or NULL

Definition at line 79 of file rsa.c.

79  {
81 
83  if ( prefix->digest == digest )
84  return prefix;
85  }
86  return NULL;
87 }
char prefix[4]
Definition: vmconsole.c:53
#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
struct digest_algorithm * digest
Digest algorithm.
Definition: rsa.h:44
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define RSA_DIGESTINFO_PREFIXES
RSA digestInfo prefix table.
Definition: rsa.h:52

References rsa_digestinfo_prefix::digest, for_each_table_entry, NULL, prefix, and RSA_DIGESTINFO_PREFIXES.

Referenced by rsa_encode_digest().

◆ rsa_free()

static void rsa_free ( struct rsa_context context)
inlinestatic

Free RSA dynamic storage.

Parameters
contextRSA context

Definition at line 94 of file rsa.c.

94  {
95 
96  free ( context->dynamic );
97 }
void * dynamic
Allocated memory.
Definition: rsa.c:53
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54

References rsa_context::dynamic, and free.

Referenced by rsa_decrypt(), rsa_encrypt(), rsa_init(), rsa_sign(), and rsa_verify().

◆ rsa_alloc()

static int rsa_alloc ( struct rsa_context context,
size_t  modulus_len,
size_t  exponent_len 
)
static

Allocate RSA dynamic storage.

Parameters
contextRSA context
modulus_lenModulus length
exponent_lenExponent length
Return values
rcReturn status code

Definition at line 107 of file rsa.c.

108  {
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 }
#define __attribute__(x)
Definition: compiler.h:10
void * tmp
Temporary working space for modular exponentiation.
Definition: rsa.c:69
bigint_element_t * output0
Output buffer.
Definition: rsa.c:67
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
unsigned int exponent_size
Exponent size.
Definition: rsa.c:63
Definition: bnxt_hsi.h:68
bigint_element_t * modulus0
Modulus.
Definition: rsa.c:55
unsigned long tmp
Definition: linux_pci.h:63
#define ENOMEM
Not enough space.
Definition: errno.h:534
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
bigint_element_t * input0
Input buffer.
Definition: rsa.c:65
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:30
unsigned char uint8_t
Definition: stdint.h:10
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:599
bigint_element_t * exponent0
Exponent.
Definition: rsa.c:61
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition: bigint.h:360
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References __attribute__, bigint_mod_exp_tmp_len, bigint_required_size, bigint_t(), rsa_context::dynamic, ENOMEM, rsa_context::exponent0, rsa_context::exponent_size, rsa_context::input0, malloc(), rsa_context::max_len, rsa_context::modulus0, rsa_context::output0, size, rsa_context::size, tmp, and rsa_context::tmp.

Referenced by rsa_init().

◆ rsa_parse_integer()

static int rsa_parse_integer ( struct asn1_cursor integer,
const struct asn1_cursor raw 
)
static

Parse RSA integer.

Parameters
integerInteger to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 147 of file rsa.c.

148  {
149 
150  /* Enter integer */
151  memcpy ( integer, raw, sizeof ( *integer ) );
152  asn1_enter ( integer, ASN1_INTEGER );
153 
154  /* Skip initial sign byte if applicable */
155  if ( ( integer->len > 1 ) &&
156  ( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
157  integer->data++;
158  integer->len--;
159  }
160 
161  /* Fail if cursor or integer are invalid */
162  if ( ! integer->len )
163  return -EINVAL;
164 
165  return 0;
166 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:205
const void * data
Start of data.
Definition: asn1.h:22
size_t len
Length of data.
Definition: asn1.h:24
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
__be32 raw[7]
Definition: CIB_PRM.h:28

References asn1_enter(), ASN1_INTEGER, asn1_cursor::data, EINVAL, asn1_cursor::len, memcpy(), and raw.

Referenced by rsa_parse_mod_exp().

◆ rsa_parse_mod_exp()

static int rsa_parse_mod_exp ( struct asn1_cursor modulus,
struct asn1_cursor exponent,
const struct asn1_cursor raw 
)
static

Parse RSA modulus and exponent.

Parameters
modulusModulus to fill in
exponentExponent to fill in
rawASN.1 cursor
Return values
rcReturn status code

Definition at line 176 of file rsa.c.

178  {
179  struct asn1_bit_string bits;
180  struct asn1_cursor cursor;
181  int is_private;
182  int rc;
183 
184  /* Enter subjectPublicKeyInfo/privateKeyInfo/RSAPrivateKey */
185  memcpy ( &cursor, raw, sizeof ( cursor ) );
186  asn1_enter ( &cursor, ASN1_SEQUENCE );
187 
188  /* Determine key format */
189  if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
190 
191  /* Private key */
192  is_private = 1;
193 
194  /* Skip version */
195  asn1_skip_any ( &cursor );
196 
197  /* Enter privateKey, if present */
198  if ( asn1_check_algorithm ( &cursor,
199  &rsa_encryption_algorithm ) == 0 ) {
200 
201  /* Skip privateKeyAlgorithm */
202  asn1_skip_any ( &cursor );
203 
204  /* Enter privateKey */
205  asn1_enter ( &cursor, ASN1_OCTET_STRING );
206 
207  /* Enter RSAPrivateKey */
208  asn1_enter ( &cursor, ASN1_SEQUENCE );
209 
210  /* Skip version */
211  asn1_skip ( &cursor, ASN1_INTEGER );
212  }
213 
214  } else {
215 
216  /* Public key */
217  is_private = 0;
218 
219  /* Skip algorithm */
220  asn1_skip ( &cursor, ASN1_SEQUENCE );
221 
222  /* Enter subjectPublicKey */
223  if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
224  return rc;
225  cursor.data = bits.data;
226  cursor.len = bits.len;
227 
228  /* Enter RSAPublicKey */
229  asn1_enter ( &cursor, ASN1_SEQUENCE );
230  }
231 
232  /* Extract modulus */
233  if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
234  return rc;
235  asn1_skip_any ( &cursor );
236 
237  /* Skip public exponent, if applicable */
238  if ( is_private )
239  asn1_skip ( &cursor, ASN1_INTEGER );
240 
241  /* Extract publicExponent/privateExponent */
242  if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
243  return rc;
244 
245  return 0;
246 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition: asn1.c:205
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:457
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:313
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int rsa_parse_integer(struct asn1_cursor *integer, const struct asn1_cursor *raw)
Parse RSA integer.
Definition: rsa.c:147
int asn1_check_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm *expected)
Check ASN.1 OID-identified algorithm.
Definition: asn1.c:680
int asn1_integral_bit_string(const struct asn1_cursor *cursor, struct asn1_bit_string *bits)
Parse ASN.1 bit string that must be an integral number of bytes.
Definition: asn1.c:451
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:89
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:62
static volatile void * bits
Definition: bitops.h:27
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition: asn1.c:254
__be32 raw[7]
Definition: CIB_PRM.h:28
struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER]
Definition: arbel.h:237
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition: asn1.h:68
An ASN.1 object cursor.
Definition: asn1.h:20
An ASN.1 bit string.
Definition: asn1.h:431

References asn1_check_algorithm(), asn1_enter(), ASN1_INTEGER, asn1_integral_bit_string(), ASN1_OCTET_STRING, ASN1_SEQUENCE, asn1_skip(), asn1_skip_any(), asn1_type(), bits, asn1_cursor::data, asn1_cursor::len, memcpy(), raw, rc, and rsa_parse_integer().

Referenced by rsa_init(), rsa_match(), and rsa_max_len().

◆ rsa_init()

static int rsa_init ( struct rsa_context context,
const struct asn1_cursor key 
)
static

Initialise RSA cipher.

Parameters
contextRSA context
keyKey
Return values
rcReturn status code

Definition at line 255 of file rsa.c.

256  {
257  struct asn1_cursor modulus;
258  struct asn1_cursor exponent;
259  int rc;
260 
261  /* Initialise context */
262  memset ( context, 0, sizeof ( *context ) );
263 
264  /* Parse modulus and exponent */
265  if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, key ) ) != 0 ){
266  DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
267  DBGC_HDA ( context, 0, key->data, key->len );
268  goto err_parse;
269  }
270 
271  DBGC ( context, "RSA %p modulus:\n", context );
272  DBGC_HDA ( context, 0, modulus.data, modulus.len );
273  DBGC ( context, "RSA %p exponent:\n", context );
274  DBGC_HDA ( context, 0, exponent.data, exponent.len );
275 
276  /* Allocate dynamic storage */
277  if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
278  goto err_alloc;
279 
280  /* Construct big integers */
281  bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
282  modulus.data, modulus.len );
283  bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
284  context->exponent0 ), exponent.data, exponent.len );
285 
286  return 0;
287 
288  rsa_free ( context );
289  err_alloc:
290  err_parse:
291  return rc;
292 }
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:176
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int exponent_size
Exponent size.
Definition: rsa.c:63
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
bigint_element_t * modulus0
Modulus.
Definition: rsa.c:55
#define DBGC_HDA(...)
Definition: compiler.h:506
unsigned int size
Modulus size.
Definition: rsa.c:57
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition: rsa.c:94
bigint_element_t * exponent0
Exponent.
Definition: rsa.c:61
An ASN.1 object cursor.
Definition: asn1.h:20
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 @383 key
Sense key.
Definition: scsi.h:18
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

References bigint_init, bigint_t(), asn1_cursor::data, DBGC, DBGC_HDA, rsa_context::exponent0, rsa_context::exponent_size, key, asn1_cursor::len, memset(), rsa_context::modulus0, rc, rsa_alloc(), rsa_free(), rsa_parse_mod_exp(), and rsa_context::size.

Referenced by rsa_decrypt(), rsa_encrypt(), rsa_sign(), and rsa_verify().

◆ rsa_max_len()

static size_t rsa_max_len ( const struct asn1_cursor key)
static

Calculate RSA maximum output length.

Parameters
keyKey
Return values
max_lenMaximum output length

Definition at line 300 of file rsa.c.

300  {
301  struct asn1_cursor modulus;
302  struct asn1_cursor exponent;
303  int rc;
304 
305  /* Parse moduli and exponents */
306  if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, key ) ) != 0 ) {
307  /* Return a zero maximum length on error */
308  return 0;
309  }
310 
311  /* Output length can never exceed modulus length */
312  return modulus.len;
313 }
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:176
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
An ASN.1 object cursor.
Definition: asn1.h:20
union @383 key
Sense key.
Definition: scsi.h:18

References key, asn1_cursor::len, rc, and rsa_parse_mod_exp().

◆ rsa_cipher()

static void rsa_cipher ( struct rsa_context context,
const void *  in,
void *  out 
)
static

Perform RSA cipher operation.

Parameters
contextRSA context
inInput buffer
outOutput buffer

Definition at line 322 of file rsa.c.

323  {
324  bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
325  bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
326  bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
327  bigint_t ( context->exponent_size ) *exponent =
328  ( ( void * ) context->exponent0 );
329 
330  /* Initialise big integer */
331  bigint_init ( input, in, context->max_len );
332 
333  /* Perform modular exponentiation */
334  bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
335 
336  /* Copy out result */
337  bigint_done ( output, out, context->max_len );
338 }
void * tmp
Temporary working space for modular exponentiation.
Definition: rsa.c:69
bigint_element_t * output0
Output buffer.
Definition: rsa.c:67
#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
unsigned int exponent_size
Exponent size.
Definition: rsa.c:63
Definition: bnxt_hsi.h:68
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
__be32 out[4]
Definition: CIB_PRM.h:36
bigint_element_t * modulus0
Modulus.
Definition: rsa.c:55
unsigned int size
Modulus size.
Definition: rsa.c:57
size_t max_len
Modulus length.
Definition: rsa.c:59
bigint_element_t * input0
Input buffer.
Definition: rsa.c:65
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:74
bigint_element_t * exponent0
Exponent.
Definition: rsa.c:61
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References bigint_done, bigint_init, bigint_mod_exp, bigint_t(), rsa_context::exponent0, rsa_context::exponent_size, in, rsa_context::input0, rsa_context::max_len, rsa_context::modulus0, out, rsa_context::output0, rsa_context::size, and rsa_context::tmp.

Referenced by rsa_decrypt(), rsa_encrypt(), rsa_sign(), and rsa_verify().

◆ rsa_encrypt()

static int rsa_encrypt ( const struct asn1_cursor key,
const void *  plaintext,
size_t  plaintext_len,
void *  ciphertext 
)
static

Encrypt using RSA.

Parameters
keyKey
plaintextPlaintext
plaintext_lenLength of plaintext
ciphertextCiphertext
Return values
ciphertext_lenLength of ciphertext, or negative error

Definition at line 349 of file rsa.c.

350  {
351  struct rsa_context context;
352  void *temp;
353  uint8_t *encoded;
354  size_t max_len;
355  size_t random_nz_len;
356  int rc;
357 
358  DBGC ( &context, "RSA %p encrypting:\n", &context );
359  DBGC_HDA ( &context, 0, plaintext, plaintext_len );
360 
361  /* Initialise context */
362  if ( ( rc = rsa_init ( &context, key ) ) != 0 )
363  goto err_init;
364 
365  /* Calculate lengths */
366  max_len = ( context.max_len - 11 );
367  random_nz_len = ( max_len - plaintext_len + 8 );
368 
369  /* Sanity check */
370  if ( plaintext_len > max_len ) {
371  DBGC ( &context, "RSA %p plaintext too long (%zd bytes, max "
372  "%zd)\n", &context, plaintext_len, max_len );
373  rc = -ERANGE;
374  goto err_sanity;
375  }
376 
377  /* Construct encoded message (using the big integer output
378  * buffer as temporary storage)
379  */
380  temp = context.output0;
381  encoded = temp;
382  encoded[0] = 0x00;
383  encoded[1] = 0x02;
384  if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
385  DBGC ( &context, "RSA %p could not generate random data: %s\n",
386  &context, strerror ( rc ) );
387  goto err_random;
388  }
389  encoded[ 2 + random_nz_len ] = 0x00;
390  memcpy ( &encoded[ context.max_len - plaintext_len ],
391  plaintext, plaintext_len );
392 
393  /* Encipher the encoded message */
394  rsa_cipher ( &context, encoded, ciphertext );
395  DBGC ( &context, "RSA %p encrypted:\n", &context );
396  DBGC_HDA ( &context, 0, ciphertext, context.max_len );
397 
398  /* Free context */
399  rsa_free ( &context );
400 
401  return context.max_len;
402 
403  err_random:
404  err_sanity:
405  rsa_free ( &context );
406  err_init:
407  return rc;
408 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
int get_random_nz(void *data, size_t len)
Get random non-zero bytes.
Definition: random_nz.c:62
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition: rsa.c:322
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An RSA context.
Definition: rsa.c:51
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.c:59
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
unsigned char uint8_t
Definition: stdint.h:10
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition: rsa.c:255
union @383 key
Sense key.
Definition: scsi.h:18

References DBGC, DBGC_HDA, ERANGE, get_random_nz(), key, rsa_context::max_len, memcpy(), rsa_context::output0, rc, rsa_cipher(), rsa_free(), rsa_init(), and strerror().

◆ rsa_decrypt()

static int rsa_decrypt ( const struct asn1_cursor key,
const void *  ciphertext,
size_t  ciphertext_len,
void *  plaintext 
)
static

Decrypt using RSA.

Parameters
keyKey
ciphertextCiphertext
ciphertext_lenCiphertext length
plaintextPlaintext
Return values
plaintext_lenPlaintext length, or negative error

Definition at line 419 of file rsa.c.

420  {
421  struct rsa_context context;
422  void *temp;
423  uint8_t *encoded;
424  uint8_t *end;
425  uint8_t *zero;
426  uint8_t *start;
427  size_t plaintext_len;
428  int rc;
429 
430  DBGC ( &context, "RSA %p decrypting:\n", &context );
431  DBGC_HDA ( &context, 0, ciphertext, ciphertext_len );
432 
433  /* Initialise context */
434  if ( ( rc = rsa_init ( &context, key ) ) != 0 )
435  goto err_init;
436 
437  /* Sanity check */
438  if ( ciphertext_len != context.max_len ) {
439  DBGC ( &context, "RSA %p ciphertext incorrect length (%zd "
440  "bytes, should be %zd)\n",
441  &context, ciphertext_len, context.max_len );
442  rc = -ERANGE;
443  goto err_sanity;
444  }
445 
446  /* Decipher the message (using the big integer input buffer as
447  * temporary storage)
448  */
449  temp = context.input0;
450  encoded = temp;
451  rsa_cipher ( &context, ciphertext, encoded );
452 
453  /* Parse the message */
454  end = ( encoded + context.max_len );
455  if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) ) {
456  rc = -EINVAL;
457  goto err_invalid;
458  }
459  zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
460  if ( ! zero ) {
461  rc = -EINVAL;
462  goto err_invalid;
463  }
464  start = ( zero + 1 );
465  plaintext_len = ( end - start );
466 
467  /* Copy out message */
468  memcpy ( plaintext, start, plaintext_len );
469  DBGC ( &context, "RSA %p decrypted:\n", &context );
470  DBGC_HDA ( &context, 0, plaintext, plaintext_len );
471 
472  /* Free context */
473  rsa_free ( &context );
474 
475  return plaintext_len;
476 
477  err_invalid:
478  DBGC ( &context, "RSA %p invalid decrypted message:\n", &context );
479  DBGC_HDA ( &context, 0, encoded, context.max_len );
480  err_sanity:
481  rsa_free ( &context );
482  err_init:
483  return rc;
484 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition: rsa.c:322
void * memchr(const void *src, int character, size_t len)
Find character within a memory region.
Definition: string.c:135
uint32_t start
Starting offset.
Definition: netvsc.h:12
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An RSA context.
Definition: rsa.c:51
#define DBGC_HDA(...)
Definition: compiler.h:506
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
unsigned char uint8_t
Definition: stdint.h:10
uint32_t end
Ending offset.
Definition: netvsc.h:18
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition: rsa.c:255
union @383 key
Sense key.
Definition: scsi.h:18

References DBGC, DBGC_HDA, EINVAL, end, ERANGE, rsa_context::input0, key, rsa_context::max_len, memchr(), memcpy(), rc, rsa_cipher(), rsa_free(), rsa_init(), and start.

◆ rsa_encode_digest()

static int rsa_encode_digest ( struct rsa_context context,
struct digest_algorithm digest,
const void *  value,
void *  encoded 
)
static

Encode RSA digest.

Parameters
contextRSA context
digestDigest algorithm
valueDigest value
encodedEncoded digest
Return values
rcReturn status code

Definition at line 495 of file rsa.c.

497  {
499  size_t digest_len = digest->digestsize;
500  uint8_t *temp = encoded;
501  size_t digestinfo_len;
502  size_t max_len;
503  size_t pad_len;
504 
505  /* Identify prefix */
507  if ( ! prefix ) {
508  DBGC ( context, "RSA %p has no prefix for %s\n",
509  context, digest->name );
510  return -ENOTSUP;
511  }
512  digestinfo_len = ( prefix->len + digest_len );
513 
514  /* Sanity check */
515  max_len = ( context->max_len - 11 );
516  if ( digestinfo_len > max_len ) {
517  DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, "
518  "max %zd)\n", context, digest->name, digestinfo_len,
519  max_len );
520  return -ERANGE;
521  }
522  DBGC ( context, "RSA %p encoding %s digest:\n",
523  context, digest->name );
524  DBGC_HDA ( context, 0, value, digest_len );
525 
526  /* Construct encoded message */
527  *(temp++) = 0x00;
528  *(temp++) = 0x01;
529  pad_len = ( max_len - digestinfo_len + 8 );
530  memset ( temp, 0xff, pad_len );
531  temp += pad_len;
532  *(temp++) = 0x00;
533  memcpy ( temp, prefix->data, prefix->len );
534  temp += prefix->len;
535  memcpy ( temp, value, digest_len );
536  temp += digest_len;
537  assert ( temp == ( encoded + context->max_len ) );
538  DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
539  DBGC_HDA ( context, 0, encoded, context->max_len );
540 
541  return 0;
542 }
#define DBGC(...)
Definition: compiler.h:505
char prefix[4]
Definition: vmconsole.c:53
static struct rsa_digestinfo_prefix * rsa_find_prefix(struct digest_algorithm *digest)
Identify RSA prefix.
Definition: rsa.c:79
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.c:59
#define ERANGE
Result too large.
Definition: errno.h:639
An RSA digestInfo prefix.
Definition: rsa.h:42
unsigned char uint8_t
Definition: stdint.h:10
long pad_len
Definition: bigint.h:30
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
struct digest_algorithm * digest
Digest algorithm.
Definition: rsa.h:44
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), DBGC, DBGC_HDA, rsa_digestinfo_prefix::digest, digest_algorithm::digestsize, ENOTSUP, ERANGE, rsa_context::max_len, memcpy(), memset(), digest_algorithm::name, pad_len, prefix, rsa_find_prefix(), and value.

Referenced by rsa_sign(), and rsa_verify().

◆ rsa_sign()

static int rsa_sign ( const struct asn1_cursor key,
struct digest_algorithm digest,
const void *  value,
void *  signature 
)
static

Sign digest value using RSA.

Parameters
keyKey
digestDigest algorithm
valueDigest value
signatureSignature
Return values
signature_lenSignature length, or negative error

Definition at line 553 of file rsa.c.

555  {
556  struct rsa_context context;
557  void *temp;
558  int rc;
559 
560  DBGC ( &context, "RSA %p signing %s digest:\n",
561  &context, digest->name );
562  DBGC_HDA ( &context, 0, value, digest->digestsize );
563 
564  /* Initialise context */
565  if ( ( rc = rsa_init ( &context, key ) ) != 0 )
566  goto err_init;
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  goto err_encode;
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  /* Free context */
581  rsa_free ( &context );
582 
583  return context.max_len;
584 
585  err_encode:
586  rsa_free ( &context );
587  err_init:
588  return rc;
589 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.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:495
#define DBGC(...)
Definition: compiler.h:505
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition: rsa.c:322
An RSA context.
Definition: rsa.c:51
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define DBGC_HDA(...)
Definition: compiler.h:506
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition: rsa.c:94
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition: rsa.c:255
u8 signature
CPU signature.
Definition: CIB_PRM.h:35
union @383 key
Sense key.
Definition: scsi.h:18

References DBGC, DBGC_HDA, digest_algorithm::digestsize, key, rsa_context::max_len, digest_algorithm::name, rsa_context::output0, rc, rsa_cipher(), rsa_encode_digest(), rsa_free(), rsa_init(), signature, and value.

◆ rsa_verify()

static int rsa_verify ( const struct asn1_cursor key,
struct digest_algorithm digest,
const void *  value,
const void *  signature,
size_t  signature_len 
)
static

Verify signed digest value using RSA.

Parameters
keyKey
digestDigest algorithm
valueDigest value
signatureSignature
signature_lenSignature length
Return values
rcReturn status code

Definition at line 601 of file rsa.c.

603  {
604  struct rsa_context context;
605  void *temp;
606  void *expected;
607  void *actual;
608  int rc;
609 
610  DBGC ( &context, "RSA %p verifying %s digest:\n",
611  &context, digest->name );
612  DBGC_HDA ( &context, 0, value, digest->digestsize );
613  DBGC_HDA ( &context, 0, signature, signature_len );
614 
615  /* Initialise context */
616  if ( ( rc = rsa_init ( &context, key ) ) != 0 )
617  goto err_init;
618 
619  /* Sanity check */
620  if ( signature_len != context.max_len ) {
621  DBGC ( &context, "RSA %p signature incorrect length (%zd "
622  "bytes, should be %zd)\n",
623  &context, signature_len, context.max_len );
624  rc = -ERANGE;
625  goto err_sanity;
626  }
627 
628  /* Decipher the signature (using the big integer input buffer
629  * as temporary storage)
630  */
631  temp = context.input0;
632  expected = temp;
633  rsa_cipher ( &context, signature, expected );
634  DBGC ( &context, "RSA %p deciphered signature:\n", &context );
635  DBGC_HDA ( &context, 0, expected, context.max_len );
636 
637  /* Encode digest (using the big integer output buffer as
638  * temporary storage)
639  */
640  temp = context.output0;
641  actual = temp;
642  if ( ( rc = rsa_encode_digest ( &context, digest, value,
643  actual ) ) != 0 )
644  goto err_encode;
645 
646  /* Verify the signature */
647  if ( memcmp ( actual, expected, context.max_len ) != 0 ) {
648  DBGC ( &context, "RSA %p signature verification failed\n",
649  &context );
650  rc = -EACCES_VERIFY;
651  goto err_verify;
652  }
653 
654  /* Free context */
655  rsa_free ( &context );
656 
657  DBGC ( &context, "RSA %p signature verified successfully\n", &context );
658  return 0;
659 
660  err_verify:
661  err_encode:
662  err_sanity:
663  rsa_free ( &context );
664  err_init:
665  return rc;
666 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.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:495
#define DBGC(...)
Definition: compiler.h:505
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition: rsa.c:322
#define EACCES_VERIFY
Definition: rsa.c:45
An RSA context.
Definition: rsa.c:51
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define DBGC_HDA(...)
Definition: compiler.h:506
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
size_t digestsize
Digest size.
Definition: crypto.h:26
const char * name
Algorithm name.
Definition: crypto.h:20
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition: rsa.c:255
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
union @383 key
Sense key.
Definition: scsi.h:18

References DBGC, DBGC_HDA, digest_algorithm::digestsize, EACCES_VERIFY, ERANGE, rsa_context::input0, key, rsa_context::max_len, memcmp(), digest_algorithm::name, rsa_context::output0, rc, rsa_cipher(), rsa_encode_digest(), rsa_free(), rsa_init(), signature, and value.

◆ rsa_match()

static int rsa_match ( const struct asn1_cursor private_key,
const struct asn1_cursor public_key 
)
static

Check for matching RSA public/private key pair.

Parameters
private_keyPrivate key
public_keyPublic key
Return values
rcReturn status code

Definition at line 675 of file rsa.c.

676  {
677  struct asn1_cursor private_modulus;
678  struct asn1_cursor private_exponent;
679  struct asn1_cursor public_modulus;
680  struct asn1_cursor public_exponent;
681  int rc;
682 
683  /* Parse moduli and exponents */
684  if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
685  private_key ) ) != 0 )
686  return rc;
687  if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
688  public_key ) ) != 0 )
689  return rc;
690 
691  /* Compare moduli */
692  if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
693  return -ENOTTY;
694 
695  return 0;
696 }
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:176
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition: asn1.c:480
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
A private key.
Definition: privkey.h:16
An ASN.1 object cursor.
Definition: asn1.h:20

References asn1_compare(), ENOTTY, rc, and rsa_parse_mod_exp().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( rsa_algorithm  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto  )

Variable Documentation

◆ rsa_algorithm

struct pubkey_algorithm rsa_algorithm
Initial value:
= {
.name = "rsa",
.max_len = rsa_max_len,
.encrypt = rsa_encrypt,
.decrypt = rsa_decrypt,
.sign = rsa_sign,
.verify = rsa_verify,
.match = rsa_match,
}
static int rsa_sign(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, void *signature)
Sign digest value using RSA.
Definition: rsa.c:553
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:675
static int rsa_decrypt(const struct asn1_cursor *key, const void *ciphertext, size_t ciphertext_len, void *plaintext)
Decrypt using RSA.
Definition: rsa.c:419
static int rsa_verify(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Verify signed digest value using RSA.
Definition: rsa.c:601
static size_t rsa_max_len(const struct asn1_cursor *key)
Calculate RSA maximum output length.
Definition: rsa.c:300
static int rsa_encrypt(const struct asn1_cursor *key, const void *plaintext, size_t plaintext_len, void *ciphertext)
Encrypt using RSA.
Definition: rsa.c:349

RSA public-key algorithm.

Definition at line 699 of file rsa.c.

Referenced by icert_cert().