iPXE
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.

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 (void *ctx, const void *key, size_t key_len)
 Initialise RSA cipher. More...
 
static size_t rsa_max_len (void *ctx)
 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 (void *ctx, const void *plaintext, size_t plaintext_len, void *ciphertext)
 Encrypt using RSA. More...
 
static int rsa_decrypt (void *ctx, 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 (void *ctx, struct digest_algorithm *digest, const void *value, void *signature)
 Sign digest value using RSA. More...
 
static int rsa_verify (void *ctx, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
 Verify signed digest value using RSA. More...
 
static void rsa_final (void *ctx)
 Finalise RSA cipher. More...
 
static int rsa_match (const void *private_key, size_t private_key_len, const void *public_key, size_t public_key_len)
 Check for matching RSA public/private key pair. More...
 
 REQUIRING_SYMBOL (rsa_algorithm)
 
 REQUIRE_OBJECT (config_crypto)
 

Variables

static uint8_t oid_rsa_encryption [] = { ASN1_OID_RSAENCRYPTION }
 "rsaEncryption" object identifier More...
 
struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm
 "rsaEncryption" OID-identified algorithm More...
 
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 68 of file rsa.c.

68  {
70 
72  if ( prefix->digest == digest )
73  return prefix;
74  }
75  return NULL;
76 }
char prefix[4]
Definition: vmconsole.c:53
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
An RSA digestInfo prefix.
Definition: rsa.h:42
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define RSA_DIGESTINFO_PREFIXES
RSA digestInfo prefix table.
Definition: rsa.h:52

References 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)
static

Free RSA dynamic storage.

Parameters
contextRSA context

Definition at line 83 of file rsa.c.

83  {
84 
85  free ( context->dynamic );
86  context->dynamic = NULL;
87 }
void * dynamic
Allocated memory.
Definition: rsa.h:61
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References rsa_context::dynamic, free, and NULL.

Referenced by rsa_alloc(), rsa_final(), and rsa_init().

◆ 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 97 of file rsa.c.

98  {
99  unsigned int size = bigint_required_size ( modulus_len );
100  unsigned int exponent_size = bigint_required_size ( exponent_len );
101  bigint_t ( size ) *modulus;
102  bigint_t ( exponent_size ) *exponent;
103  size_t tmp_len = bigint_mod_exp_tmp_len ( modulus, exponent );
104  struct {
105  bigint_t ( size ) modulus;
106  bigint_t ( exponent_size ) exponent;
107  bigint_t ( size ) input;
108  bigint_t ( size ) output;
110  } __attribute__ (( packed )) *dynamic;
111 
112  /* Free any existing dynamic storage */
113  rsa_free ( context );
114 
115  /* Allocate dynamic storage */
116  dynamic = malloc ( sizeof ( *dynamic ) );
117  if ( ! dynamic )
118  return -ENOMEM;
119 
120  /* Assign dynamic storage */
121  context->dynamic = dynamic;
122  context->modulus0 = &dynamic->modulus.element[0];
123  context->size = size;
124  context->max_len = modulus_len;
125  context->exponent0 = &dynamic->exponent.element[0];
126  context->exponent_size = exponent_size;
127  context->input0 = &dynamic->input.element[0];
128  context->output0 = &dynamic->output.element[0];
129  context->tmp = &dynamic->tmp;
130 
131  return 0;
132 }
#define __attribute__(x)
Definition: compiler.h:10
void * tmp
Temporary working space for modular exponentiation.
Definition: rsa.h:77
bigint_element_t * output0
Output buffer.
Definition: rsa.h:75
return tmp_len
Definition: entropy.h:241
unsigned int exponent_size
Exponent size.
Definition: rsa.h:71
bigint_element_t * modulus0
Modulus.
Definition: rsa.h:63
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define bigint_mod_exp_tmp_len(modulus, exponent)
Calculate temporary working space required for moduluar exponentiation.
Definition: bigint.h:248
unsigned int size
Modulus size.
Definition: rsa.h:65
size_t max_len
Modulus length.
Definition: rsa.h:67
void * dynamic
Allocated memory.
Definition: rsa.h:61
bigint_element_t * input0
Input buffer.
Definition: rsa.h:73
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition: rsa.c:83
const bigint_t(size) __attribute__((may_alias)) *reference
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:28
uint8_t * tmp
Definition: entropy.h:156
unsigned char uint8_t
Definition: stdint.h:10
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
bigint_element_t * exponent0
Exponent.
Definition: rsa.h:69
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16

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, rsa_free(), size, rsa_context::size, rsa_context::tmp, tmp, and tmp_len.

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 141 of file rsa.c.

142  {
143 
144  /* Enter integer */
145  memcpy ( integer, raw, sizeof ( *integer ) );
146  asn1_enter ( integer, ASN1_INTEGER );
147 
148  /* Skip initial sign byte if applicable */
149  if ( ( integer->len > 1 ) &&
150  ( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
151  integer->data++;
152  integer->len--;
153  }
154 
155  /* Fail if cursor or integer are invalid */
156  if ( ! integer->len )
157  return -EINVAL;
158 
159  return 0;
160 }
#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:160
const void * data
Start of data.
Definition: asn1.h:21
size_t len
Length of data.
Definition: asn1.h:23
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:61
__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 170 of file rsa.c.

172  {
173  struct asn1_bit_string bits;
174  struct asn1_cursor cursor;
175  int is_private;
176  int rc;
177 
178  /* Enter subjectPublicKeyInfo/RSAPrivateKey */
179  memcpy ( &cursor, raw, sizeof ( cursor ) );
180  asn1_enter ( &cursor, ASN1_SEQUENCE );
181 
182  /* Determine key format */
183  if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
184 
185  /* Private key */
186  is_private = 1;
187 
188  /* Skip version */
189  asn1_skip_any ( &cursor );
190 
191  } else {
192 
193  /* Public key */
194  is_private = 0;
195 
196  /* Skip algorithm */
197  asn1_skip ( &cursor, ASN1_SEQUENCE );
198 
199  /* Enter subjectPublicKey */
200  if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
201  return rc;
202  cursor.data = bits.data;
203  cursor.len = bits.len;
204 
205  /* Enter RSAPublicKey */
206  asn1_enter ( &cursor, ASN1_SEQUENCE );
207  }
208 
209  /* Extract modulus */
210  if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
211  return rc;
212  asn1_skip_any ( &cursor );
213 
214  /* Skip public exponent, if applicable */
215  if ( is_private )
216  asn1_skip ( &cursor, ASN1_INTEGER );
217 
218  /* Extract publicExponent/privateExponent */
219  if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
220  return rc;
221 
222  return 0;
223 }
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:160
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition: asn1.h:342
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition: asn1.c:276
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:141
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:414
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition: asn1.h:85
#define ASN1_INTEGER
ASN.1 integer.
Definition: asn1.h:61
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:218
__be32 raw[7]
Definition: CIB_PRM.h:28
struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER]
Definition: arbel.h:237
An ASN.1 object cursor.
Definition: asn1.h:19
An ASN.1 bit string.
Definition: asn1.h:316

References asn1_enter(), ASN1_INTEGER, asn1_integral_bit_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(), and rsa_match().

◆ rsa_init()

static int rsa_init ( void *  ctx,
const void *  key,
size_t  key_len 
)
static

Initialise RSA cipher.

Parameters
ctxRSA context
keyKey
key_lenLength of key
Return values
rcReturn status code

Definition at line 233 of file rsa.c.

233  {
234  struct rsa_context *context = ctx;
235  struct asn1_cursor modulus;
236  struct asn1_cursor exponent;
237  struct asn1_cursor cursor;
238  int rc;
239 
240  /* Initialise context */
241  memset ( context, 0, sizeof ( *context ) );
242 
243  /* Initialise cursor */
244  cursor.data = key;
245  cursor.len = key_len;
246 
247  /* Parse modulus and exponent */
248  if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, &cursor ) ) != 0 ){
249  DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
250  DBGC_HDA ( context, 0, cursor.data, cursor.len );
251  goto err_parse;
252  }
253 
254  DBGC ( context, "RSA %p modulus:\n", context );
255  DBGC_HDA ( context, 0, modulus.data, modulus.len );
256  DBGC ( context, "RSA %p exponent:\n", context );
257  DBGC_HDA ( context, 0, exponent.data, exponent.len );
258 
259  /* Allocate dynamic storage */
260  if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
261  goto err_alloc;
262 
263  /* Construct big integers */
264  bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
265  modulus.data, modulus.len );
266  bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
267  context->exponent0 ), exponent.data, exponent.len );
268 
269  return 0;
270 
271  rsa_free ( context );
272  err_alloc:
273  err_parse:
274  return rc;
275 }
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:170
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
unsigned int exponent_size
Exponent size.
Definition: rsa.h:71
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:48
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
bigint_element_t * modulus0
Modulus.
Definition: rsa.h:63
An RSA context.
Definition: rsa.h:59
#define DBGC_HDA(...)
Definition: compiler.h:506
unsigned int size
Modulus size.
Definition: rsa.h:65
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition: rsa.c:83
const bigint_t(size) __attribute__((may_alias)) *reference
bigint_element_t * exponent0
Exponent.
Definition: rsa.h:69
An ASN.1 object cursor.
Definition: asn1.h:19
static int rsa_alloc(struct rsa_context *context, size_t modulus_len, size_t exponent_len)
Allocate RSA dynamic storage.
Definition: rsa.c:97
union @375 key
Sense key.
Definition: scsi.h:18
void * memset(void *dest, int character, size_t len) __nonnull

References bigint_init, bigint_t(), ctx, 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.

◆ rsa_max_len()

static size_t rsa_max_len ( void *  ctx)
static

Calculate RSA maximum output length.

Parameters
ctxRSA context
Return values
max_lenMaximum output length

Definition at line 283 of file rsa.c.

283  {
284  struct rsa_context *context = ctx;
285 
286  return context->max_len;
287 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
An RSA context.
Definition: rsa.h:59
size_t max_len
Modulus length.
Definition: rsa.h:67

References ctx, and rsa_context::max_len.

◆ 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 296 of file rsa.c.

297  {
298  bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
299  bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
300  bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
301  bigint_t ( context->exponent_size ) *exponent =
302  ( ( void * ) context->exponent0 );
303 
304  /* Initialise big integer */
305  bigint_init ( input, in, context->max_len );
306 
307  /* Perform modular exponentiation */
308  bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
309 
310  /* Copy out result */
311  bigint_done ( output, out, context->max_len );
312 }
void * tmp
Temporary working space for modular exponentiation.
Definition: rsa.h:77
bigint_element_t * output0
Output buffer.
Definition: rsa.h:75
#define bigint_mod_exp(base, modulus, exponent, result, tmp)
Perform modular exponentiation of big integers.
Definition: bigint.h:233
__be32 in[4]
Definition: CIB_PRM.h:35
unsigned int exponent_size
Exponent size.
Definition: rsa.h:71
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:48
bigint_element_t * modulus0
Modulus.
Definition: rsa.h:63
unsigned int size
Modulus size.
Definition: rsa.h:65
size_t max_len
Modulus length.
Definition: rsa.h:67
bigint_element_t * input0
Input buffer.
Definition: rsa.h:73
__be32 out[4]
Definition: CIB_PRM.h:36
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:61
const bigint_t(size) __attribute__((may_alias)) *reference
bigint_element_t * exponent0
Exponent.
Definition: rsa.h:69

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 ( void *  ctx,
const void *  plaintext,
size_t  plaintext_len,
void *  ciphertext 
)
static

Encrypt using RSA.

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

Definition at line 323 of file rsa.c.

324  {
325  struct rsa_context *context = ctx;
326  void *temp;
327  uint8_t *encoded;
328  size_t max_len = ( context->max_len - 11 );
329  size_t random_nz_len = ( max_len - plaintext_len + 8 );
330  int rc;
331 
332  /* Sanity check */
333  if ( plaintext_len > max_len ) {
334  DBGC ( context, "RSA %p plaintext too long (%zd bytes, max "
335  "%zd)\n", context, plaintext_len, max_len );
336  return -ERANGE;
337  }
338  DBGC ( context, "RSA %p encrypting:\n", context );
339  DBGC_HDA ( context, 0, plaintext, plaintext_len );
340 
341  /* Construct encoded message (using the big integer output
342  * buffer as temporary storage)
343  */
344  temp = context->output0;
345  encoded = temp;
346  encoded[0] = 0x00;
347  encoded[1] = 0x02;
348  if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
349  DBGC ( context, "RSA %p could not generate random data: %s\n",
350  context, strerror ( rc ) );
351  return rc;
352  }
353  encoded[ 2 + random_nz_len ] = 0x00;
354  memcpy ( &encoded[ context->max_len - plaintext_len ],
355  plaintext, plaintext_len );
356 
357  /* Encipher the encoded message */
358  rsa_cipher ( context, encoded, ciphertext );
359  DBGC ( context, "RSA %p encrypted:\n", context );
360  DBGC_HDA ( context, 0, ciphertext, context->max_len );
361 
362  return context->max_len;
363 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
bigint_element_t * output0
Output buffer.
Definition: rsa.h:75
static void size_t size_t max_len
Definition: entropy.h:153
#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:296
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An RSA context.
Definition: rsa.h:59
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.h:67
#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

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

◆ rsa_decrypt()

static int rsa_decrypt ( void *  ctx,
const void *  ciphertext,
size_t  ciphertext_len,
void *  plaintext 
)
static

Decrypt using RSA.

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

Definition at line 374 of file rsa.c.

375  {
376  struct rsa_context *context = ctx;
377  void *temp;
378  uint8_t *encoded;
379  uint8_t *end;
380  uint8_t *zero;
381  uint8_t *start;
382  size_t plaintext_len;
383 
384  /* Sanity check */
385  if ( ciphertext_len != context->max_len ) {
386  DBGC ( context, "RSA %p ciphertext incorrect length (%zd "
387  "bytes, should be %zd)\n",
388  context, ciphertext_len, context->max_len );
389  return -ERANGE;
390  }
391  DBGC ( context, "RSA %p decrypting:\n", context );
392  DBGC_HDA ( context, 0, ciphertext, ciphertext_len );
393 
394  /* Decipher the message (using the big integer input buffer as
395  * temporary storage)
396  */
397  temp = context->input0;
398  encoded = temp;
399  rsa_cipher ( context, ciphertext, encoded );
400 
401  /* Parse the message */
402  end = ( encoded + context->max_len );
403  if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) )
404  goto invalid;
405  zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
406  if ( ! zero )
407  goto invalid;
408  start = ( zero + 1 );
409  plaintext_len = ( end - start );
410 
411  /* Copy out message */
412  memcpy ( plaintext, start, plaintext_len );
413  DBGC ( context, "RSA %p decrypted:\n", context );
414  DBGC_HDA ( context, 0, plaintext, plaintext_len );
415 
416  return plaintext_len;
417 
418  invalid:
419  DBGC ( context, "RSA %p invalid decrypted message:\n", context );
420  DBGC_HDA ( context, 0, encoded, context->max_len );
421  return -EINVAL;
422 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#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:296
uint32_t zero
Must be zero.
Definition: ntlm.h:24
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
void * memchr(const void *src, int character, size_t len)
Find character within a memory region.
Definition: string.c:119
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.h:59
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.h:67
bigint_element_t * input0
Input buffer.
Definition: rsa.h:73
#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

References ctx, DBGC, DBGC_HDA, EINVAL, end, ERANGE, rsa_context::input0, rsa_context::max_len, memchr(), memcpy(), rsa_cipher(), start, and zero.

◆ 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 433 of file rsa.c.

435  {
437  size_t digest_len = digest->digestsize;
438  uint8_t *temp = encoded;
439  size_t digestinfo_len;
440  size_t max_len;
441  size_t pad_len;
442 
443  /* Identify prefix */
445  if ( ! prefix ) {
446  DBGC ( context, "RSA %p has no prefix for %s\n",
447  context, digest->name );
448  return -ENOTSUP;
449  }
450  digestinfo_len = ( prefix->len + digest_len );
451 
452  /* Sanity check */
453  max_len = ( context->max_len - 11 );
454  if ( digestinfo_len > max_len ) {
455  DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, max"
456  "%zd)\n",
457  context, digest->name, digestinfo_len, max_len );
458  return -ERANGE;
459  }
460  DBGC ( context, "RSA %p encoding %s digest:\n",
461  context, digest->name );
462  DBGC_HDA ( context, 0, value, digest_len );
463 
464  /* Construct encoded message */
465  *(temp++) = 0x00;
466  *(temp++) = 0x01;
467  pad_len = ( max_len - digestinfo_len + 8 );
468  memset ( temp, 0xff, pad_len );
469  temp += pad_len;
470  *(temp++) = 0x00;
471  memcpy ( temp, prefix->data, prefix->len );
472  temp += prefix->len;
473  memcpy ( temp, value, digest_len );
474  temp += digest_len;
475  assert ( temp == ( encoded + context->max_len ) );
476  DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
477  DBGC_HDA ( context, 0, encoded, context->max_len );
478 
479  return 0;
480 }
static void size_t size_t max_len
Definition: entropy.h:153
#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:68
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#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)
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.h:67
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#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
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by rsa_sign(), and rsa_verify().

◆ rsa_sign()

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

Sign digest value using RSA.

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

Definition at line 491 of file rsa.c.

492  {
493  struct rsa_context *context = ctx;
494  void *temp;
495  int rc;
496 
497  DBGC ( context, "RSA %p signing %s digest:\n", context, digest->name );
498  DBGC_HDA ( context, 0, value, digest->digestsize );
499 
500  /* Encode digest (using the big integer output buffer as
501  * temporary storage)
502  */
503  temp = context->output0;
504  if ( ( rc = rsa_encode_digest ( context, digest, value, temp ) ) != 0 )
505  return rc;
506 
507  /* Encipher the encoded digest */
508  rsa_cipher ( context, temp, signature );
509  DBGC ( context, "RSA %p signed %s digest:\n", context, digest->name );
510  DBGC_HDA ( context, 0, signature, context->max_len );
511 
512  return context->max_len;
513 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
bigint_element_t * output0
Output buffer.
Definition: rsa.h:75
static int rsa_encode_digest(struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
Encode RSA digest.
Definition: rsa.c:433
#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:296
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
u8 signature
Definition: CIB_PRM.h:35
An RSA context.
Definition: rsa.h:59
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.h:67
pseudo_bit_t value[0x00020]
Definition: arbel.h:13

References ctx, DBGC, DBGC_HDA, digest, rsa_context::max_len, rsa_context::output0, rc, rsa_cipher(), rsa_encode_digest(), signature, and value.

◆ rsa_verify()

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

Verify signed digest value using RSA.

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

Definition at line 525 of file rsa.c.

527  {
528  struct rsa_context *context = ctx;
529  void *temp;
530  void *expected;
531  void *actual;
532  int rc;
533 
534  /* Sanity check */
535  if ( signature_len != context->max_len ) {
536  DBGC ( context, "RSA %p signature incorrect length (%zd "
537  "bytes, should be %zd)\n",
538  context, signature_len, context->max_len );
539  return -ERANGE;
540  }
541  DBGC ( context, "RSA %p verifying %s digest:\n",
542  context, digest->name );
543  DBGC_HDA ( context, 0, value, digest->digestsize );
544  DBGC_HDA ( context, 0, signature, signature_len );
545 
546  /* Decipher the signature (using the big integer input buffer
547  * as temporary storage)
548  */
549  temp = context->input0;
550  expected = temp;
551  rsa_cipher ( context, signature, expected );
552  DBGC ( context, "RSA %p deciphered signature:\n", context );
553  DBGC_HDA ( context, 0, expected, context->max_len );
554 
555  /* Encode digest (using the big integer output buffer as
556  * temporary storage)
557  */
558  temp = context->output0;
559  actual = temp;
560  if ( ( rc = rsa_encode_digest ( context, digest, value, actual ) ) !=0 )
561  return rc;
562 
563  /* Verify the signature */
564  if ( memcmp ( actual, expected, context->max_len ) != 0 ) {
565  DBGC ( context, "RSA %p signature verification failed\n",
566  context );
567  return -EACCES_VERIFY;
568  }
569 
570  DBGC ( context, "RSA %p signature verified successfully\n", context );
571  return 0;
572 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
bigint_element_t * output0
Output buffer.
Definition: rsa.h:75
static int rsa_encode_digest(struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
Encode RSA digest.
Definition: rsa.c:433
#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:296
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
#define EACCES_VERIFY
Definition: rsa.c:45
u8 signature
Definition: CIB_PRM.h:35
An RSA context.
Definition: rsa.h:59
#define DBGC_HDA(...)
Definition: compiler.h:506
size_t max_len
Modulus length.
Definition: rsa.h:67
bigint_element_t * input0
Input buffer.
Definition: rsa.h:73
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define ERANGE
Result too large.
Definition: errno.h:639
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98

References ctx, DBGC, DBGC_HDA, digest, EACCES_VERIFY, ERANGE, rsa_context::input0, rsa_context::max_len, memcmp(), rsa_context::output0, rc, rsa_cipher(), rsa_encode_digest(), signature, and value.

◆ rsa_final()

static void rsa_final ( void *  ctx)
static

Finalise RSA cipher.

Parameters
ctxRSA context

Definition at line 579 of file rsa.c.

579  {
580  struct rsa_context *context = ctx;
581 
582  rsa_free ( context );
583 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
An RSA context.
Definition: rsa.h:59
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition: rsa.c:83

References ctx, and rsa_free().

◆ rsa_match()

static int rsa_match ( const void *  private_key,
size_t  private_key_len,
const void *  public_key,
size_t  public_key_len 
)
static

Check for matching RSA public/private key pair.

Parameters
private_keyPrivate key
private_key_lenPrivate key length
public_keyPublic key
public_key_lenPublic key length
Return values
rcReturn status code

Definition at line 594 of file rsa.c.

595  {
596  struct asn1_cursor private_modulus;
597  struct asn1_cursor private_exponent;
598  struct asn1_cursor private_cursor;
599  struct asn1_cursor public_modulus;
600  struct asn1_cursor public_exponent;
601  struct asn1_cursor public_cursor;
602  int rc;
603 
604  /* Initialise cursors */
605  private_cursor.data = private_key;
606  private_cursor.len = private_key_len;
607  public_cursor.data = public_key;
608  public_cursor.len = public_key_len;
609 
610  /* Parse moduli and exponents */
611  if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
612  &private_cursor ) ) != 0 )
613  return rc;
614  if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
615  &public_cursor ) ) != 0 )
616  return rc;
617 
618  /* Compare moduli */
619  if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
620  return -ENOTTY;
621 
622  return 0;
623 }
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:170
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:443
size_t len
Length of data.
Definition: asn1.h:23
char private_key_len[]
struct asn1_cursor private_key
Private key.
Definition: privkey.c:67
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER]
Definition: arbel.h:237
An ASN.1 object cursor.
Definition: asn1.h:19

References asn1_compare(), asn1_cursor::data, ENOTTY, asn1_cursor::len, private_key, private_key_len, rc, and rsa_parse_mod_exp().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( rsa_algorithm  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto  )

Variable Documentation

◆ oid_rsa_encryption

uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION }
static

"rsaEncryption" object identifier

Definition at line 51 of file rsa.c.

◆ __asn1_algorithm

struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm
Initial value:
= {
.name = "rsaEncryption",
.pubkey = &rsa_algorithm,
.digest = NULL,
}
static uint8_t oid_rsa_encryption[]
"rsaEncryption" object identifier
Definition: rsa.c:51
#define ASN1_OID_CURSOR(oid_value)
Define an ASN.1 cursor containing an OID.
Definition: asn1.h:292
struct pubkey_algorithm rsa_algorithm
RSA public-key algorithm.
Definition: rsa.c:626
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

"rsaEncryption" OID-identified algorithm

Definition at line 54 of file rsa.c.

◆ rsa_algorithm

struct pubkey_algorithm rsa_algorithm
Initial value:
= {
.name = "rsa",
.ctxsize = RSA_CTX_SIZE,
.init = rsa_init,
.max_len = rsa_max_len,
.encrypt = rsa_encrypt,
.decrypt = rsa_decrypt,
.sign = rsa_sign,
.verify = rsa_verify,
.final = rsa_final,
.match = rsa_match,
}
static int rsa_encrypt(void *ctx, const void *plaintext, size_t plaintext_len, void *ciphertext)
Encrypt using RSA.
Definition: rsa.c:323
static int rsa_decrypt(void *ctx, const void *ciphertext, size_t ciphertext_len, void *plaintext)
Decrypt using RSA.
Definition: rsa.c:374
static void rsa_final(void *ctx)
Finalise RSA cipher.
Definition: rsa.c:579
static int rsa_verify(void *ctx, struct digest_algorithm *digest, const void *value, const void *signature, size_t signature_len)
Verify signed digest value using RSA.
Definition: rsa.c:525
#define RSA_CTX_SIZE
RSA context size.
Definition: rsa.h:81
static int rsa_init(void *ctx, const void *key, size_t key_len)
Initialise RSA cipher.
Definition: rsa.c:233
static int rsa_match(const void *private_key, size_t private_key_len, const void *public_key, size_t public_key_len)
Check for matching RSA public/private key pair.
Definition: rsa.c:594
static int rsa_sign(void *ctx, struct digest_algorithm *digest, const void *value, void *signature)
Sign digest value using RSA.
Definition: rsa.c:491
static size_t rsa_max_len(void *ctx)
Calculate RSA maximum output length.
Definition: rsa.c:283

RSA public-key algorithm.

Definition at line 626 of file rsa.c.