iPXE
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)
 FILE_SECBOOT (PERMITTED)
static struct rsa_digestinfo_prefixrsa_find_prefix (struct digest_algorithm *digest)
 Identify RSA prefix.
static void rsa_free (struct rsa_context *context)
 Free RSA dynamic storage.
static int rsa_alloc (struct rsa_context *context, size_t modulus_len, size_t exponent_len)
 Allocate RSA dynamic storage.
static int rsa_parse_mod_exp (struct asn1_cursor *modulus, struct asn1_cursor *exponent, const struct asn1_cursor *raw)
 Parse RSA modulus and exponent.
static int rsa_init (struct rsa_context *context, const struct asn1_cursor *key)
 Initialise RSA cipher.
static void rsa_cipher (struct rsa_context *context, const void *in, void *out)
 Perform RSA cipher operation.
static int rsa_encrypt (const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
 Encrypt using RSA.
static int rsa_decrypt (const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
 Decrypt using RSA.
static int rsa_encode_digest (struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
 Encode RSA digest.
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.
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.
static int rsa_match (const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
 Check for matching RSA public/private key pair.
 REQUIRING_SYMBOL (rsa_algorithm)
 REQUIRE_OBJECT (config_crypto)

Variables

struct pubkey_algorithm rsa_algorithm
 RSA public-key algorithm.

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

46#define EACCES_VERIFY \
47 __einfo_error ( EINFO_EACCES_VERIFY )

Referenced by rsa_verify().

◆ EINFO_EACCES_VERIFY

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

Definition at line 48 of file rsa.c.

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ rsa_find_prefix()

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

80 {
82
84 if ( prefix->digest == digest )
85 return prefix;
86 }
87 return NULL;
88}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define RSA_DIGESTINFO_PREFIXES
RSA digestInfo prefix table.
Definition rsa.h:53
An RSA digestInfo prefix.
Definition rsa.h:43
struct digest_algorithm * digest
Digest algorithm.
Definition rsa.h:45
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
char prefix[4]
Definition vmconsole.c:53

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

Referenced by rsa_encode_digest().

◆ rsa_free()

void rsa_free ( struct rsa_context * context)
inlinestatic

Free RSA dynamic storage.

Parameters
contextRSA context

Definition at line 95 of file rsa.c.

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

References rsa_context::dynamic, and free.

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

◆ rsa_alloc()

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

109 {
110 unsigned int size = bigint_required_size ( modulus_len );
111 unsigned int exponent_size = bigint_required_size ( exponent_len );
112 bigint_t ( size ) *modulus;
113 size_t tmp_len = bigint_mod_exp_tmp_len ( modulus );
114 struct {
115 bigint_t ( size ) modulus;
116 bigint_t ( exponent_size ) exponent;
117 bigint_t ( size ) input;
118 bigint_t ( size ) output;
119 uint8_t tmp[tmp_len];
120 } __attribute__ (( packed )) *dynamic;
121
122 /* Allocate dynamic storage */
123 dynamic = malloc ( sizeof ( *dynamic ) );
124 if ( ! dynamic )
125 return -ENOMEM;
126
127 /* Assign dynamic storage */
128 context->dynamic = dynamic;
129 context->modulus0 = &dynamic->modulus.element[0];
130 context->size = size;
131 context->max_len = modulus_len;
132 context->exponent0 = &dynamic->exponent.element[0];
133 context->exponent_size = exponent_size;
134 context->input0 = &dynamic->input.element[0];
135 context->output0 = &dynamic->output.element[0];
136 context->tmp = &dynamic->tmp;
137
138 return 0;
139}
unsigned char uint8_t
Definition stdint.h:10
uint16_t size
Buffer size.
Definition dwmac.h:3
#define ENOMEM
Not enough space.
Definition errno.h:535
#define __attribute__(x)
Definition compiler.h:10
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition bigint.h:361
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:31
unsigned long tmp
Definition linux_pci.h:65
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
bigint_element_t * exponent0
Exponent.
Definition rsa.c:62
bigint_element_t * input0
Input buffer.
Definition rsa.c:66
void * tmp
Temporary working space for modular exponentiation.
Definition rsa.c:70
bigint_element_t * modulus0
Modulus.
Definition rsa.c:56
unsigned int exponent_size
Exponent size.
Definition rsa.c:64
bigint_element_t * output0
Output buffer.
Definition rsa.c:68
size_t max_len
Modulus length.
Definition rsa.c:60
unsigned int size
Modulus size.
Definition rsa.c:58

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_context::size, size, rsa_context::tmp, and tmp.

Referenced by rsa_init().

◆ rsa_parse_mod_exp()

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

151 {
152 struct asn1_cursor cursor;
153 int is_private;
154 int rc;
155
156 /* Enter subjectPublicKeyInfo/privateKeyInfo/RSAPrivateKey */
157 memcpy ( &cursor, raw, sizeof ( cursor ) );
158 asn1_enter ( &cursor, ASN1_SEQUENCE );
159
160 /* Determine key format */
161 if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
162
163 /* Private key */
164 is_private = 1;
165
166 /* Skip version */
167 asn1_skip_any ( &cursor );
168
169 /* Enter privateKey, if present */
170 if ( asn1_check_algorithm ( &cursor, &rsa_encryption_algorithm,
171 NULL ) == 0 ) {
172
173 /* Skip privateKeyAlgorithm */
174 asn1_skip_any ( &cursor );
175
176 /* Enter privateKey */
177 asn1_enter ( &cursor, ASN1_OCTET_STRING );
178
179 /* Enter RSAPrivateKey */
180 asn1_enter ( &cursor, ASN1_SEQUENCE );
181
182 /* Skip version */
183 asn1_skip ( &cursor, ASN1_INTEGER );
184 }
185
186 } else {
187
188 /* Public key */
189 is_private = 0;
190
191 /* Skip algorithm */
192 asn1_skip ( &cursor, ASN1_SEQUENCE );
193
194 /* Enter subjectPublicKey */
195 asn1_enter_bits ( &cursor, NULL );
196
197 /* Enter RSAPublicKey */
198 asn1_enter ( &cursor, ASN1_SEQUENCE );
199 }
200
201 /* Extract modulus */
202 memcpy ( modulus, &cursor, sizeof ( *modulus ) );
203 if ( ( rc = asn1_enter_unsigned ( modulus ) ) != 0 )
204 return rc;
205 asn1_skip_any ( &cursor );
206
207 /* Skip public exponent, if applicable */
208 if ( is_private )
209 asn1_skip ( &cursor, ASN1_INTEGER );
210
211 /* Extract publicExponent/privateExponent */
212 memcpy ( exponent, &cursor, sizeof ( *exponent ) );
213 if ( ( rc = asn1_enter_unsigned ( exponent ) ) != 0 )
214 return rc;
215
216 return 0;
217}
__be32 raw[7]
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
int asn1_enter_unsigned(struct asn1_cursor *cursor)
Enter ASN.1 unsigned integer.
Definition asn1.c:369
int asn1_skip_any(struct asn1_cursor *cursor)
Skip ASN.1 object of any type.
Definition asn1.c:290
int asn1_check_algorithm(const struct asn1_cursor *cursor, struct asn1_algorithm *expected, struct asn1_cursor *params)
Check ASN.1 OID-identified algorithm.
Definition asn1.c:705
int asn1_enter(struct asn1_cursor *cursor, unsigned int type)
Enter ASN.1 object.
Definition asn1.c:169
int asn1_skip(struct asn1_cursor *cursor, unsigned int type)
Skip ASN.1 object.
Definition asn1.c:231
int asn1_enter_bits(struct asn1_cursor *cursor, unsigned int *unused)
Enter ASN.1 bit string.
Definition asn1.c:311
#define ASN1_INTEGER
ASN.1 integer.
Definition asn1.h:63
#define ASN1_SEQUENCE
ASN.1 sequence.
Definition asn1.h:90
#define ASN1_OCTET_STRING
ASN.1 octet string.
Definition asn1.h:69
static unsigned int asn1_type(const struct asn1_cursor *cursor)
Extract ASN.1 type.
Definition asn1.h:479
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An ASN.1 object cursor.
Definition asn1.h:21

References asn1_check_algorithm(), asn1_enter(), asn1_enter_bits(), asn1_enter_unsigned(), ASN1_INTEGER, ASN1_OCTET_STRING, ASN1_SEQUENCE, asn1_skip(), asn1_skip_any(), asn1_type(), memcpy(), NULL, raw, and rc.

Referenced by rsa_init(), and rsa_match().

◆ rsa_init()

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

227 {
228 struct asn1_cursor modulus;
229 struct asn1_cursor exponent;
230 int rc;
231
232 /* Initialise context */
233 memset ( context, 0, sizeof ( *context ) );
234
235 /* Parse modulus and exponent */
236 if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, key ) ) != 0 ){
237 DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
238 DBGC_HDA ( context, 0, key->data, key->len );
239 goto err_parse;
240 }
241
242 DBGC ( context, "RSA %p modulus:\n", context );
243 DBGC_HDA ( context, 0, modulus.data, modulus.len );
244 DBGC ( context, "RSA %p exponent:\n", context );
245 DBGC_HDA ( context, 0, exponent.data, exponent.len );
246
247 /* Allocate dynamic storage */
248 if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
249 goto err_alloc;
250
251 /* Construct big integers */
252 bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
253 modulus.data, modulus.len );
254 bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
255 context->exponent0 ), exponent.data, exponent.len );
256
257 return 0;
258
259 rsa_free ( context );
260 err_alloc:
261 err_parse:
262 return rc;
263}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
void * memset(void *dest, int character, size_t len) __nonnull
static void rsa_free(struct rsa_context *context)
Free RSA dynamic storage.
Definition rsa.c:95
static int rsa_parse_mod_exp(struct asn1_cursor *modulus, struct asn1_cursor *exponent, const struct asn1_cursor *raw)
Parse RSA modulus and exponent.
Definition rsa.c:149
static int rsa_alloc(struct rsa_context *context, size_t modulus_len, size_t exponent_len)
Allocate RSA dynamic storage.
Definition rsa.c:108

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_cipher()

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

273 {
274 bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
275 bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
276 bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
277 bigint_t ( context->exponent_size ) *exponent =
278 ( ( void * ) context->exponent0 );
279
280 /* Initialise big integer */
281 bigint_init ( input, in, context->max_len );
282
283 /* Perform modular exponentiation */
284 bigint_mod_exp ( input, modulus, exponent, output, context->tmp );
285
286 /* Copy out result */
287 bigint_done ( output, out, context->max_len );
288}
__be32 in[4]
Definition CIB_PRM.h:7
__be32 out[4]
Definition CIB_PRM.h:8
#define bigint_mod_exp(base, modulus, exponent, result, tmp)
Perform modular exponentiation of big integers.
Definition bigint.h:347
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75

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()

int rsa_encrypt ( const struct asn1_cursor * key,
const struct asn1_cursor * plaintext,
struct asn1_builder * ciphertext )
static

Encrypt using RSA.

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

Definition at line 298 of file rsa.c.

300 {
301 struct rsa_context context;
302 void *temp;
303 uint8_t *encoded;
304 size_t max_len;
305 size_t random_nz_len;
306 int rc;
307
308 DBGC ( &context, "RSA %p encrypting:\n", &context );
309 DBGC_HDA ( &context, 0, plaintext->data, plaintext->len );
310
311 /* Initialise context */
312 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
313 goto err_init;
314
315 /* Calculate lengths */
316 max_len = ( context.max_len - 11 );
317 random_nz_len = ( max_len - plaintext->len + 8 );
318
319 /* Sanity check */
320 if ( plaintext->len > max_len ) {
321 DBGC ( &context, "RSA %p plaintext too long (%zd bytes, max "
322 "%zd)\n", &context, plaintext->len, max_len );
323 rc = -ERANGE;
324 goto err_sanity;
325 }
326
327 /* Construct encoded message (using the big integer output
328 * buffer as temporary storage)
329 */
330 temp = context.output0;
331 encoded = temp;
332 encoded[0] = 0x00;
333 encoded[1] = 0x02;
334 if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
335 DBGC ( &context, "RSA %p could not generate random data: %s\n",
336 &context, strerror ( rc ) );
337 goto err_random;
338 }
339 encoded[ 2 + random_nz_len ] = 0x00;
340 memcpy ( &encoded[ context.max_len - plaintext->len ],
341 plaintext->data, plaintext->len );
342
343 /* Create space for ciphertext */
344 if ( ( rc = asn1_grow ( ciphertext, context.max_len ) ) != 0 )
345 goto err_grow;
346
347 /* Encipher the encoded message */
348 rsa_cipher ( &context, encoded, ciphertext->data );
349 DBGC ( &context, "RSA %p encrypted:\n", &context );
350 DBGC_HDA ( &context, 0, ciphertext->data, context.max_len );
351
352 /* Free context */
353 rsa_free ( &context );
354
355 return 0;
356
357 err_grow:
358 err_random:
359 err_sanity:
360 rsa_free ( &context );
361 err_init:
362 return rc;
363}
int asn1_grow(struct asn1_builder *builder, size_t extra)
Grow ASN.1 builder.
Definition asn1.c:916
#define ERANGE
Result too large.
Definition errno.h:640
int get_random_nz(void *data, size_t len)
Get random non-zero bytes.
Definition random_nz.c:63
static int rsa_init(struct rsa_context *context, const struct asn1_cursor *key)
Initialise RSA cipher.
Definition rsa.c:226
static void rsa_cipher(struct rsa_context *context, const void *in, void *out)
Perform RSA cipher operation.
Definition rsa.c:272
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
void * data
Data.
Definition asn1.h:36
const void * data
Start of data.
Definition asn1.h:23
size_t len
Length of data.
Definition asn1.h:25
An RSA context.
Definition rsa.c:52

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

◆ rsa_decrypt()

int rsa_decrypt ( const struct asn1_cursor * key,
const struct asn1_cursor * ciphertext,
struct asn1_builder * plaintext )
static

Decrypt using RSA.

Parameters
keyKey
ciphertextCiphertext
plaintextPlaintext
Return values
rcReturn status code

Definition at line 373 of file rsa.c.

375 {
376 struct rsa_context context;
377 void *temp;
378 uint8_t *encoded;
379 uint8_t *end;
380 uint8_t *zero;
381 uint8_t *start;
382 size_t len;
383 int rc;
384
385 DBGC ( &context, "RSA %p decrypting:\n", &context );
386 DBGC_HDA ( &context, 0, ciphertext->data, ciphertext->len );
387
388 /* Initialise context */
389 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
390 goto err_init;
391
392 /* Sanity check */
393 if ( ciphertext->len != context.max_len ) {
394 DBGC ( &context, "RSA %p ciphertext incorrect length (%zd "
395 "bytes, should be %zd)\n",
396 &context, ciphertext->len, context.max_len );
397 rc = -ERANGE;
398 goto err_sanity;
399 }
400
401 /* Decipher the message (using the big integer input buffer as
402 * temporary storage)
403 */
404 temp = context.input0;
405 encoded = temp;
406 rsa_cipher ( &context, ciphertext->data, encoded );
407
408 /* Parse the message */
409 end = ( encoded + context.max_len );
410 if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) ) {
411 rc = -EINVAL;
412 goto err_invalid;
413 }
414 zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
415 if ( ! zero ) {
416 DBGC ( &context, "RSA %p invalid decrypted message:\n",
417 &context );
418 DBGC_HDA ( &context, 0, encoded, context.max_len );
419 rc = -EINVAL;
420 goto err_invalid;
421 }
422 start = ( zero + 1 );
423 len = ( end - start );
424
425 /* Create space for plaintext */
426 if ( ( rc = asn1_grow ( plaintext, len ) ) != 0 )
427 goto err_grow;
428
429 /* Copy out message */
430 memcpy ( plaintext->data, start, len );
431 DBGC ( &context, "RSA %p decrypted:\n", &context );
432 DBGC_HDA ( &context, 0, plaintext->data, len );
433
434 /* Free context */
435 rsa_free ( &context );
436
437 return 0;
438
439 err_grow:
440 err_invalid:
441 err_sanity:
442 rsa_free ( &context );
443 err_init:
444 return rc;
445}
ring len
Length.
Definition dwmac.h:226
uint32_t start
Starting offset.
Definition netvsc.h:1
#define EINVAL
Invalid argument.
Definition errno.h:429
uint32_t end
Ending offset.
Definition netvsc.h:7
void * memchr(const void *src, int character, size_t len)
Find character within a memory region.
Definition string.c:136

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

◆ rsa_encode_digest()

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

458 {
460 size_t digest_len = digest->digestsize;
461 uint8_t *temp = encoded;
462 size_t digestinfo_len;
463 size_t max_len;
464 size_t pad_len;
465
466 /* Identify prefix */
468 if ( ! prefix ) {
469 DBGC ( context, "RSA %p has no prefix for %s\n",
470 context, digest->name );
471 return -ENOTSUP;
472 }
473 digestinfo_len = ( prefix->len + digest_len );
474
475 /* Sanity check */
476 max_len = ( context->max_len - 11 );
477 if ( digestinfo_len > max_len ) {
478 DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, "
479 "max %zd)\n", context, digest->name, digestinfo_len,
480 max_len );
481 return -ERANGE;
482 }
483 DBGC ( context, "RSA %p encoding %s digest:\n",
484 context, digest->name );
485 DBGC_HDA ( context, 0, value, digest_len );
486
487 /* Construct encoded message */
488 *(temp++) = 0x00;
489 *(temp++) = 0x01;
490 pad_len = ( max_len - digestinfo_len + 8 );
491 memset ( temp, 0xff, pad_len );
492 temp += pad_len;
493 *(temp++) = 0x00;
494 memcpy ( temp, prefix->data, prefix->len );
495 temp += prefix->len;
496 memcpy ( temp, value, digest_len );
497 temp += digest_len;
498 assert ( temp == ( encoded + context->max_len ) );
499 DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
500 DBGC_HDA ( context, 0, encoded, context->max_len );
501
502 return 0;
503}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
long pad_len
Definition bigint.h:31
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define ENOTSUP
Operation not supported.
Definition errno.h:590
static struct rsa_digestinfo_prefix * rsa_find_prefix(struct digest_algorithm *digest)
Identify RSA prefix.
Definition rsa.c:80
size_t digestsize
Digest size.
Definition crypto.h:27
const char * name
Algorithm name.
Definition crypto.h:21

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()

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

Sign digest value using RSA.

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

Definition at line 514 of file rsa.c.

516 {
517 struct rsa_context context;
518 int rc;
519
520 DBGC ( &context, "RSA %p signing %s digest:\n",
521 &context, digest->name );
522 DBGC_HDA ( &context, 0, value, digest->digestsize );
523
524 /* Initialise context */
525 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
526 goto err_init;
527
528 /* Create space for encoded digest and signature */
529 if ( ( rc = asn1_grow ( signature, context.max_len ) ) != 0 )
530 goto err_grow;
531
532 /* Encode digest */
533 if ( ( rc = rsa_encode_digest ( &context, digest, value,
534 signature->data ) ) != 0 )
535 goto err_encode;
536
537 /* Encipher the encoded digest */
538 rsa_cipher ( &context, signature->data, signature->data );
539 DBGC ( &context, "RSA %p signed %s digest:\n", &context, digest->name );
540 DBGC_HDA ( &context, 0, signature->data, signature->len );
541
542 /* Free context */
543 rsa_free ( &context );
544
545 return 0;
546
547 err_encode:
548 err_grow:
549 rsa_free ( &context );
550 err_init:
551 return rc;
552}
u8 signature
CPU signature.
Definition CIB_PRM.h:7
static int rsa_encode_digest(struct rsa_context *context, struct digest_algorithm *digest, const void *value, void *encoded)
Encode RSA digest.
Definition rsa.c:456

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

◆ rsa_verify()

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

Verify signed digest value using RSA.

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

Definition at line 563 of file rsa.c.

565 {
566 struct rsa_context context;
567 void *temp;
568 void *expected;
569 void *actual;
570 int rc;
571
572 DBGC ( &context, "RSA %p verifying %s digest:\n",
573 &context, digest->name );
574 DBGC_HDA ( &context, 0, value, digest->digestsize );
575 DBGC_HDA ( &context, 0, signature->data, signature->len );
576
577 /* Initialise context */
578 if ( ( rc = rsa_init ( &context, key ) ) != 0 )
579 goto err_init;
580
581 /* Sanity check */
582 if ( signature->len != context.max_len ) {
583 DBGC ( &context, "RSA %p signature incorrect length (%zd "
584 "bytes, should be %zd)\n",
585 &context, signature->len, context.max_len );
586 rc = -ERANGE;
587 goto err_sanity;
588 }
589
590 /* Decipher the signature (using the big integer input buffer
591 * as temporary storage)
592 */
593 temp = context.input0;
594 expected = temp;
595 rsa_cipher ( &context, signature->data, expected );
596 DBGC ( &context, "RSA %p deciphered signature:\n", &context );
597 DBGC_HDA ( &context, 0, expected, context.max_len );
598
599 /* Encode digest (using the big integer output buffer as
600 * temporary storage)
601 */
602 temp = context.output0;
603 actual = temp;
604 if ( ( rc = rsa_encode_digest ( &context, digest, value,
605 actual ) ) != 0 )
606 goto err_encode;
607
608 /* Verify the signature */
609 if ( memcmp ( actual, expected, context.max_len ) != 0 ) {
610 DBGC ( &context, "RSA %p signature verification failed\n",
611 &context );
612 rc = -EACCES_VERIFY;
613 goto err_verify;
614 }
615
616 /* Free context */
617 rsa_free ( &context );
618
619 DBGC ( &context, "RSA %p signature verified successfully\n", &context );
620 return 0;
621
622 err_verify:
623 err_encode:
624 err_sanity:
625 rsa_free ( &context );
626 err_init:
627 return rc;
628}
#define EACCES_VERIFY
Definition rsa.c:46
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

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()

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

638 {
639 struct asn1_cursor private_modulus;
640 struct asn1_cursor private_exponent;
641 struct asn1_cursor public_modulus;
642 struct asn1_cursor public_exponent;
643 int rc;
644
645 /* Parse moduli and exponents */
646 if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
647 private_key ) ) != 0 )
648 return rc;
649 if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
650 public_key ) ) != 0 )
651 return rc;
652
653 /* Compare moduli */
654 if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
655 return -ENOTTY;
656
657 return 0;
658}
int asn1_compare(const struct asn1_cursor *cursor1, const struct asn1_cursor *cursor2)
Compare two ASN.1 objects.
Definition asn1.c:458
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
A private key.
Definition privkey.h:17

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

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( rsa_algorithm )

References rsa_algorithm.

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_crypto )

Variable Documentation

◆ rsa_algorithm

struct pubkey_algorithm rsa_algorithm
Initial value:
= {
.name = "rsa",
.encrypt = rsa_encrypt,
.decrypt = rsa_decrypt,
.sign = rsa_sign,
.verify = rsa_verify,
.match = rsa_match,
}
static int rsa_verify(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature)
Verify signed digest value using RSA.
Definition rsa.c:563
static int rsa_match(const struct asn1_cursor *private_key, const struct asn1_cursor *public_key)
Check for matching RSA public/private key pair.
Definition rsa.c:637
static int rsa_sign(const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature)
Sign digest value using RSA.
Definition rsa.c:514
static int rsa_decrypt(const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext)
Decrypt using RSA.
Definition rsa.c:373
static int rsa_encrypt(const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext)
Encrypt using RSA.
Definition rsa.c:298

RSA public-key algorithm.

Definition at line 661 of file rsa.c.

661 {
662 .name = "rsa",
663 .encrypt = rsa_encrypt,
664 .decrypt = rsa_decrypt,
665 .sign = rsa_sign,
666 .verify = rsa_verify,
667 .match = rsa_match,
668};

Referenced by __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), __tls_cipher_suite(), icert_cert(), PUBKEY_SIGN_TEST(), PUBKEY_SIGN_TEST(), PUBKEY_SIGN_TEST(), PUBKEY_TEST(), PUBKEY_TEST(), and REQUIRING_SYMBOL().