Browse Source

[crypto] Add native RSA algorithm

Add an implementation of RSA that uses the iPXE big-integer support.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
299dedcff0
4 changed files with 728 additions and 3 deletions
  1. 0
    0
      src/crypto/axtls/axtls_rsa.c
  2. 600
    0
      src/crypto/rsa.c
  3. 1
    0
      src/include/ipxe/errfile.h
  4. 127
    3
      src/include/ipxe/rsa.h

src/crypto/axtls/rsa.c → src/crypto/axtls/axtls_rsa.c View File


+ 600
- 0
src/crypto/rsa.c View File

1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+#include <stdint.h>
22
+#include <stdlib.h>
23
+#include <stdarg.h>
24
+#include <string.h>
25
+#include <errno.h>
26
+#include <ipxe/asn1.h>
27
+#include <ipxe/crypto.h>
28
+#include <ipxe/bigint.h>
29
+#include <ipxe/random_nz.h>
30
+#include <ipxe/md5.h>
31
+#include <ipxe/sha1.h>
32
+#include <ipxe/sha256.h>
33
+#include <ipxe/rsa.h>
34
+
35
+/** @file
36
+ *
37
+ * RSA public-key cryptography
38
+ *
39
+ * RSA is documented in RFC 3447.
40
+ */
41
+
42
+/** An RSA digestInfo prefix */
43
+struct rsa_digestinfo_prefix {
44
+	/** Digest algorithm */
45
+	struct digest_algorithm *digest;
46
+	/** Prefix */
47
+	const void *data;
48
+	/** Length of prefix */
49
+	size_t len;
50
+};
51
+
52
+/** "id-md5" object identifier */
53
+static const uint8_t rsa_md5_prefix[] =
54
+	{ RSA_DIGESTINFO_PREFIX ( MD5_DIGEST_SIZE, ASN1_OID_MD5 ) };
55
+
56
+/** "id-sha1" object identifier */
57
+static const uint8_t rsa_sha1_prefix[] =
58
+	{ RSA_DIGESTINFO_PREFIX ( SHA1_DIGEST_SIZE, ASN1_OID_SHA1 ) };
59
+
60
+/** "id-sha256" object identifier */
61
+static const uint8_t rsa_sha256_prefix[] =
62
+	{ RSA_DIGESTINFO_PREFIX ( SHA256_DIGEST_SIZE, ASN1_OID_SHA256 ) };
63
+
64
+/** RSA digestInfo prefixes */
65
+static struct rsa_digestinfo_prefix rsa_digestinfo_prefixes[] = {
66
+	{
67
+		.digest = &md5_algorithm,
68
+		.data = rsa_md5_prefix,
69
+		.len = sizeof ( rsa_md5_prefix ),
70
+	},
71
+	{
72
+		.digest = &sha1_algorithm,
73
+		.data = rsa_sha1_prefix,
74
+		.len = sizeof ( rsa_sha1_prefix ),
75
+	},
76
+	{
77
+		.digest = &sha256_algorithm,
78
+		.data = rsa_sha256_prefix,
79
+		.len = sizeof ( rsa_sha256_prefix ),
80
+	},
81
+};
82
+
83
+/**
84
+ * Identify RSA prefix
85
+ *
86
+ * @v digest		Digest algorithm
87
+ * @ret prefix		RSA prefix, or NULL
88
+ */
89
+static struct rsa_digestinfo_prefix *
90
+rsa_find_prefix ( struct digest_algorithm *digest ) {
91
+	struct rsa_digestinfo_prefix *prefix;
92
+	unsigned int i;
93
+
94
+	for ( i = 0 ; i < ( sizeof ( rsa_digestinfo_prefixes ) /
95
+			    sizeof ( rsa_digestinfo_prefixes[0] ) ) ; i++ ) {
96
+		prefix = &rsa_digestinfo_prefixes[i];
97
+		if ( prefix->digest == digest )
98
+			return prefix;
99
+	}
100
+	return NULL;
101
+}
102
+
103
+/**
104
+ * Free RSA dynamic storage
105
+ *
106
+ * @v context		RSA context
107
+ */
108
+static void rsa_free ( struct rsa_context *context ) {
109
+
110
+	free ( context->dynamic );
111
+	context->dynamic = NULL;
112
+}
113
+
114
+/**
115
+ * Allocate RSA dynamic storage
116
+ *
117
+ * @v context		RSA context
118
+ * @v modulus_len	Modulus length
119
+ * @v exponent_len	Exponent length
120
+ * @ret rc		Return status code
121
+ */
122
+static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
123
+		       size_t exponent_len ) {
124
+	unsigned int size = bigint_required_size ( modulus_len );
125
+	unsigned int exponent_size = bigint_required_size ( exponent_len );
126
+	struct {
127
+		bigint_t ( size ) modulus;
128
+		bigint_t ( exponent_size ) exponent;
129
+		bigint_t ( size ) input;
130
+		bigint_t ( size ) output;
131
+	} __attribute__ (( packed )) *dynamic;
132
+
133
+	/* Free any existing dynamic storage */
134
+	rsa_free ( context );
135
+
136
+	/* Allocate dynamic storage */
137
+	dynamic = malloc ( sizeof ( *dynamic ) );
138
+	if ( ! dynamic )
139
+		return -ENOMEM;
140
+
141
+	/* Assign dynamic storage */
142
+	context->dynamic = dynamic;
143
+	context->modulus0 = &dynamic->modulus.element[0];
144
+	context->size = size;
145
+	context->max_len = modulus_len;
146
+	context->exponent0 = &dynamic->exponent.element[0];
147
+	context->exponent_size = exponent_size;
148
+	context->input0 = &dynamic->input.element[0];
149
+	context->output0 = &dynamic->output.element[0];
150
+
151
+	return 0;
152
+}
153
+
154
+/**
155
+ * Parse RSA integer
156
+ *
157
+ * @v context		RSA context
158
+ * @v integer		Integer to fill in
159
+ * @v raw		ASN.1 cursor
160
+ * @ret rc		Return status code
161
+ */
162
+static int rsa_parse_integer ( struct rsa_context *context,
163
+			       struct asn1_cursor *integer,
164
+			       const struct asn1_cursor *raw ) {
165
+
166
+	/* Enter integer */
167
+	memcpy ( integer, raw, sizeof ( *integer ) );
168
+	asn1_enter ( integer, ASN1_INTEGER );
169
+
170
+	/* Skip initial sign byte if applicable */
171
+	if ( ( integer->len > 1 ) &&
172
+	     ( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
173
+		integer->data++;
174
+		integer->len--;
175
+	}
176
+
177
+	/* Fail if cursor or integer are invalid */
178
+	if ( ! integer->len ) {
179
+		DBGC ( context, "RSA %p invalid integer:\n", context );
180
+		DBGC_HDA ( context, 0, raw->data, raw->len );
181
+		return -EINVAL;
182
+	}
183
+
184
+	return 0;
185
+}
186
+
187
+/**
188
+ * Initialise RSA cipher
189
+ *
190
+ * @v ctx		RSA context
191
+ * @v key		Key
192
+ * @v key_len		Length of key
193
+ * @ret rc		Return status code
194
+ */
195
+static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
196
+	struct rsa_context *context = ctx;
197
+	const struct asn1_bit_string *bit_string;
198
+	struct asn1_cursor modulus;
199
+	struct asn1_cursor exponent;
200
+	struct asn1_cursor cursor;
201
+	int is_private;
202
+	int rc;
203
+
204
+	/* Initialise context */
205
+	memset ( context, 0, sizeof ( *context ) );
206
+
207
+	/* Initialise cursor */
208
+	cursor.data = key;
209
+	cursor.len = key_len;
210
+
211
+	/* Enter subjectPublicKeyInfo/RSAPrivateKey */
212
+	asn1_enter ( &cursor, ASN1_SEQUENCE );
213
+
214
+	/* Determine key format */
215
+	if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
216
+		/* Private key */
217
+		is_private = 1;
218
+
219
+		/* Skip version */
220
+		asn1_skip_any ( &cursor );
221
+
222
+	} else {
223
+		/* Public key */
224
+		is_private = 0;
225
+
226
+		/* Skip algorithm */
227
+		asn1_skip ( &cursor, ASN1_SEQUENCE );
228
+
229
+		/* Enter subjectPublicKey */
230
+		asn1_enter ( &cursor, ASN1_BIT_STRING );
231
+
232
+		/* Check and skip unused-bits byte of bit string */
233
+		bit_string = cursor.data;
234
+		if ( cursor.len < 1 ) {
235
+			rc = -EINVAL;
236
+			goto err_parse;
237
+		}
238
+		cursor.data++;
239
+		cursor.len--;
240
+
241
+		/* Enter RSAPublicKey */
242
+		asn1_enter ( &cursor, ASN1_SEQUENCE );
243
+	}
244
+
245
+	/* Extract modulus */
246
+	if ( ( rc = rsa_parse_integer ( context, &modulus, &cursor ) ) != 0 )
247
+		goto err_parse;
248
+	asn1_skip_any ( &cursor );
249
+
250
+	/* Skip public exponent, if applicable */
251
+	if ( is_private )
252
+		asn1_skip ( &cursor, ASN1_INTEGER );
253
+
254
+	/* Extract publicExponent/privateExponent */
255
+	if ( ( rc = rsa_parse_integer ( context, &exponent, &cursor ) ) != 0 )
256
+		goto err_parse;
257
+
258
+	DBGC ( context, "RSA %p modulus:\n", context );
259
+	DBGC_HDA ( context, 0, modulus.data, modulus.len );
260
+	DBGC ( context, "RSA %p exponent:\n", context );
261
+	DBGC_HDA ( context, 0, exponent.data, exponent.len );
262
+
263
+	/* Allocate dynamic storage */
264
+	if ( ( rc = rsa_alloc ( context, modulus.len, exponent.len ) ) != 0 )
265
+		goto err_alloc;
266
+
267
+	/* Construct big integers */
268
+	bigint_init ( ( ( bigint_t ( context->size ) * ) context->modulus0 ),
269
+		      modulus.data, modulus.len );
270
+	bigint_init ( ( ( bigint_t ( context->exponent_size ) * )
271
+			context->exponent0 ), exponent.data, exponent.len );
272
+
273
+	return 0;
274
+
275
+	rsa_free ( context );
276
+ err_alloc:
277
+ err_parse:
278
+	return rc;
279
+}
280
+
281
+/**
282
+ * Calculate RSA maximum output length
283
+ *
284
+ * @v ctx		RSA context
285
+ * @ret max_len		Maximum output length
286
+ */
287
+static size_t rsa_max_len ( void *ctx ) {
288
+	struct rsa_context *context = ctx;
289
+
290
+	return context->max_len;
291
+}
292
+
293
+/**
294
+ * Perform RSA cipher operation
295
+ *
296
+ * @v context		RSA context
297
+ * @v in		Input buffer
298
+ * @v out		Output buffer
299
+ */
300
+static void rsa_cipher ( struct rsa_context *context,
301
+			 const void *in, void *out ) {
302
+	bigint_t ( context->size ) *input = ( ( void * ) context->input0 );
303
+	bigint_t ( context->size ) *output = ( ( void * ) context->output0 );
304
+	bigint_t ( context->size ) *modulus = ( ( void * ) context->modulus0 );
305
+	bigint_t ( context->exponent_size ) *exponent =
306
+		( ( void * ) context->exponent0 );
307
+
308
+	/* Initialise big integer */
309
+	bigint_init ( input, in, context->max_len );
310
+
311
+	/* Perform modular exponentiation */
312
+	bigint_mod_exp ( input, modulus, exponent, output );
313
+
314
+	/* Copy out result */
315
+	bigint_done ( output, out, context->max_len );
316
+}
317
+
318
+/**
319
+ * Encrypt using RSA
320
+ *
321
+ * @v ctx		RSA context
322
+ * @v plaintext		Plaintext
323
+ * @v plaintext_len	Length of plaintext
324
+ * @v ciphertext	Ciphertext
325
+ * @ret ciphertext_len	Length of ciphertext, or negative error
326
+ */
327
+static int rsa_encrypt ( void *ctx, const void *plaintext,
328
+			 size_t plaintext_len, void *ciphertext ) {
329
+	struct rsa_context *context = ctx;
330
+	void *temp;
331
+	uint8_t *encoded;
332
+	size_t max_len = ( context->max_len - 11 );
333
+	size_t random_nz_len = ( max_len - plaintext_len + 8 );
334
+	int rc;
335
+
336
+	/* Sanity check */
337
+	if ( plaintext_len > max_len ) {
338
+		DBGC ( context, "RSA %p plaintext too long (%zd bytes, max "
339
+		       "%zd)\n", context, plaintext_len, max_len );
340
+		return -ERANGE;
341
+	}
342
+	DBGC ( context, "RSA %p encrypting:\n", context );
343
+	DBGC_HDA ( context, 0, plaintext, plaintext_len );
344
+
345
+	/* Construct encoded message (using the big integer output
346
+	 * buffer as temporary storage)
347
+	 */
348
+	temp = context->output0;
349
+	encoded = temp;
350
+	encoded[0] = 0x00;
351
+	encoded[1] = 0x02;
352
+	if ( ( rc = get_random_nz ( &encoded[2], random_nz_len ) ) != 0 ) {
353
+		DBGC ( context, "RSA %p could not generate random data: %s\n",
354
+		       context, strerror ( rc ) );
355
+		return rc;
356
+	}
357
+	encoded[ 2 + random_nz_len ] = 0x00;
358
+	memcpy ( &encoded[ context->max_len - plaintext_len ],
359
+		 plaintext, plaintext_len );
360
+
361
+	/* Encipher the encoded message */
362
+	rsa_cipher ( context, encoded, ciphertext );
363
+	DBGC ( context, "RSA %p encrypted:\n", context );
364
+	DBGC_HDA ( context, 0, ciphertext, context->max_len );
365
+
366
+	return context->max_len;
367
+}
368
+
369
+/**
370
+ * Decrypt using RSA
371
+ *
372
+ * @v ctx		RSA context
373
+ * @v ciphertext	Ciphertext
374
+ * @v ciphertext_len	Ciphertext length
375
+ * @v plaintext		Plaintext
376
+ * @ret plaintext_len	Plaintext length, or negative error
377
+ */
378
+static int rsa_decrypt ( void *ctx, const void *ciphertext,
379
+			 size_t ciphertext_len, void *plaintext ) {
380
+	struct rsa_context *context = ctx;
381
+	void *temp;
382
+	uint8_t *encoded;
383
+	uint8_t *end;
384
+	uint8_t *zero;
385
+	uint8_t *start;
386
+	size_t plaintext_len;
387
+
388
+	/* Sanity check */
389
+	if ( ciphertext_len != context->max_len ) {
390
+		DBGC ( context, "RSA %p ciphertext incorrect length (%zd "
391
+		       "bytes, should be %zd)\n",
392
+		       context, ciphertext_len, context->max_len );
393
+		return -ERANGE;
394
+	}
395
+	DBGC ( context, "RSA %p decrypting:\n", context );
396
+	DBGC_HDA ( context, 0, ciphertext, ciphertext_len );
397
+
398
+	/* Decipher the message (using the big integer input buffer as
399
+	 * temporary storage)
400
+	 */
401
+	temp = context->input0;
402
+	encoded = temp;
403
+	rsa_cipher ( context, ciphertext, encoded );
404
+
405
+	/* Parse the message */
406
+	end = ( encoded + context->max_len );
407
+	if ( ( encoded[0] != 0x00 ) || ( encoded[1] != 0x02 ) )
408
+		goto invalid;
409
+	zero = memchr ( &encoded[2], 0, ( end - &encoded[2] ) );
410
+	if ( ! zero )
411
+		goto invalid;
412
+	start = ( zero + 1 );
413
+	plaintext_len = ( end - start );
414
+
415
+	/* Copy out message */
416
+	memcpy ( plaintext, start, plaintext_len );
417
+	DBGC ( context, "RSA %p decrypted:\n", context );
418
+	DBGC_HDA ( context, 0, plaintext, plaintext_len );
419
+
420
+	return plaintext_len;
421
+
422
+ invalid:
423
+	DBGC ( context, "RSA %p invalid decrypted message:\n", context );
424
+	DBGC_HDA ( context, 0, encoded, context->max_len );
425
+	return -EINVAL;
426
+}
427
+
428
+/**
429
+ * Encode RSA digest
430
+ *
431
+ * @v context		RSA context
432
+ * @v digest		Digest algorithm
433
+ * @v value		Digest value
434
+ * @v encoded		Encoded digest
435
+ * @ret rc		Return status code
436
+ */
437
+static int rsa_encode_digest ( struct rsa_context *context,
438
+			       struct digest_algorithm *digest,
439
+			       const void *value, void *encoded ) {
440
+	struct rsa_digestinfo_prefix *prefix;
441
+	size_t digest_len = digest->digestsize;
442
+	uint8_t *temp = encoded;
443
+	size_t digestinfo_len;
444
+	size_t max_len;
445
+	size_t pad_len;
446
+
447
+	/* Identify prefix */
448
+	prefix = rsa_find_prefix ( digest );
449
+	if ( ! prefix ) {
450
+		DBGC ( context, "RSA %p has no prefix for %s\n",
451
+		       context, digest->name );
452
+		return -ENOTSUP;
453
+	}
454
+	digestinfo_len = ( prefix->len + digest_len );
455
+
456
+	/* Sanity check */
457
+	max_len = ( context->max_len - 11 );
458
+	if ( digestinfo_len > max_len ) {
459
+		DBGC ( context, "RSA %p %s digestInfo too long (%zd bytes, max"
460
+		       "%zd)\n",
461
+		       context, digest->name, digestinfo_len, max_len );
462
+		return -ERANGE;
463
+	}
464
+	DBGC ( context, "RSA %p encoding %s digest:\n",
465
+	       context, digest->name );
466
+	DBGC_HDA ( context, 0, value, digest_len );
467
+
468
+	/* Construct encoded message */
469
+	*(temp++) = 0x00;
470
+	*(temp++) = 0x01;
471
+	pad_len = ( max_len - digestinfo_len + 8 );
472
+	memset ( temp, 0xff, pad_len );
473
+	temp += pad_len;
474
+	*(temp++) = 0x00;
475
+	memcpy ( temp, prefix->data, prefix->len );
476
+	temp += prefix->len;
477
+	memcpy ( temp, value, digest_len );
478
+	temp += digest_len;
479
+	assert ( temp == ( encoded + context->max_len ) );
480
+	DBGC ( context, "RSA %p encoded %s digest:\n", context, digest->name );
481
+	DBGC_HDA ( context, 0, encoded, context->max_len );
482
+
483
+	return 0;
484
+}
485
+
486
+/**
487
+ * Sign digest value using RSA
488
+ *
489
+ * @v ctx		RSA context
490
+ * @v digest		Digest algorithm
491
+ * @v value		Digest value
492
+ * @v signature		Signature
493
+ * @ret signature_len	Signature length, or negative error
494
+ */
495
+static int rsa_sign ( void *ctx, struct digest_algorithm *digest,
496
+		      const void *value, void *signature ) {
497
+	struct rsa_context *context = ctx;
498
+	void *temp;
499
+	int rc;
500
+
501
+	DBGC ( context, "RSA %p signing %s digest:\n", context, digest->name );
502
+	DBGC_HDA ( context, 0, value, digest->digestsize );
503
+
504
+	/* Encode digest (using the big integer output buffer as
505
+	 * temporary storage)
506
+	 */
507
+	temp = context->output0;
508
+	if ( ( rc = rsa_encode_digest ( context, digest, value, temp ) ) != 0 )
509
+		return rc;
510
+
511
+	/* Encipher the encoded digest */
512
+	rsa_cipher ( context, temp, signature );
513
+	DBGC ( context, "RSA %p signed %s digest:\n", context, digest->name );
514
+	DBGC_HDA ( context, 0, signature, context->max_len );
515
+
516
+	return context->max_len;
517
+}
518
+
519
+/**
520
+ * Verify signed digest value using RSA
521
+ *
522
+ * @v ctx		RSA context
523
+ * @v digest		Digest algorithm
524
+ * @v value		Digest value
525
+ * @v signature		Signature
526
+ * @v signature_len	Signature length
527
+ * @ret rc		Return status code
528
+ */
529
+static int rsa_verify ( void *ctx, struct digest_algorithm *digest,
530
+			const void *value, const void *signature,
531
+			size_t signature_len ) {
532
+	struct rsa_context *context = ctx;
533
+	void *temp;
534
+	void *expected;
535
+	void *actual;
536
+	int rc;
537
+
538
+	/* Sanity check */
539
+	if ( signature_len != context->max_len ) {
540
+		DBGC ( context, "RSA %p signature incorrect length (%zd "
541
+		       "bytes, should be %zd)\n",
542
+		       context, signature_len, context->max_len );
543
+		return -ERANGE;
544
+	}
545
+	DBGC ( context, "RSA %p verifying %s digest:\n",
546
+	       context, digest->name );
547
+	DBGC_HDA ( context, 0, value, digest->digestsize );
548
+	DBGC_HDA ( context, 0, signature, signature_len );
549
+
550
+	/* Decipher the signature (using the big integer input buffer
551
+	 * as temporary storage)
552
+	 */
553
+	temp = context->input0;
554
+	expected = temp;
555
+	rsa_cipher ( context, signature, expected );
556
+	DBGC ( context, "RSA %p deciphered signature:\n", context );
557
+	DBGC_HDA ( context, 0, expected, context->max_len );
558
+
559
+	/* Encode digest (using the big integer output buffer as
560
+	 * temporary storage)
561
+	 */
562
+	temp = context->output0;
563
+	actual = temp;
564
+	if ( ( rc = rsa_encode_digest ( context, digest, value, actual ) ) !=0 )
565
+		return rc;
566
+
567
+	/* Verify the signature */
568
+	if ( memcmp ( actual, expected, context->max_len ) != 0 ) {
569
+		DBGC ( context, "RSA %p signature verification failed\n",
570
+		       context );
571
+		return -EACCES;
572
+	}
573
+
574
+	DBGC ( context, "RSA %p signature verified successfully\n", context );
575
+	return 0;
576
+}
577
+
578
+/**
579
+ * Finalise RSA cipher
580
+ *
581
+ * @v ctx		RSA context
582
+ */
583
+static void rsa_final ( void *ctx ) {
584
+	struct rsa_context *context = ctx;
585
+
586
+	rsa_free ( context );
587
+}
588
+
589
+/** RSA public-key algorithm */
590
+struct pubkey_algorithm rsa_algorithm = {
591
+	.name		= "rsa",
592
+	.ctxsize	= sizeof ( struct rsa_context ),
593
+	.init		= rsa_init,
594
+	.max_len	= rsa_max_len,
595
+	.encrypt	= rsa_encrypt,
596
+	.decrypt	= rsa_decrypt,
597
+	.sign		= rsa_sign,
598
+	.verify		= rsa_verify,
599
+	.final		= rsa_final,
600
+};

+ 1
- 0
src/include/ipxe/errfile.h View File

246
 #define ERRFILE_hmac_drbg	      ( ERRFILE_OTHER | 0x00240000 )
246
 #define ERRFILE_hmac_drbg	      ( ERRFILE_OTHER | 0x00240000 )
247
 #define ERRFILE_drbg		      ( ERRFILE_OTHER | 0x00250000 )
247
 #define ERRFILE_drbg		      ( ERRFILE_OTHER | 0x00250000 )
248
 #define ERRFILE_entropy		      ( ERRFILE_OTHER | 0x00260000 )
248
 #define ERRFILE_entropy		      ( ERRFILE_OTHER | 0x00260000 )
249
+#define ERRFILE_rsa		      ( ERRFILE_OTHER | 0x00270000 )
249
 
250
 
250
 /** @} */
251
 /** @} */
251
 
252
 

+ 127
- 3
src/include/ipxe/rsa.h View File

1
 #ifndef _IPXE_RSA_H
1
 #ifndef _IPXE_RSA_H
2
 #define _IPXE_RSA_H
2
 #define _IPXE_RSA_H
3
 
3
 
4
+/** @file
5
+ *
6
+ * RSA public-key cryptography
7
+ */
8
+
4
 FILE_LICENCE ( GPL2_OR_LATER );
9
 FILE_LICENCE ( GPL2_OR_LATER );
5
 
10
 
6
-struct pubkey_algorithm;
11
+#include <ipxe/crypto.h>
12
+#include <ipxe/bigint.h>
13
+#include <ipxe/asn1.h>
7
 
14
 
8
-extern struct pubkey_algorithm rsa_algorithm;
15
+/** ASN.1 OID for iso(1) member-body(2) us(840) */
16
+#define ASN1_OID_ISO_US ASN1_OID_ISO_MEMBERBODY, ASN1_OID_DOUBLE ( 840 )
17
+
18
+/** ASN.1 OID for iso(1) member-body(2) us(840) rsadsi(113549) */
19
+#define ASN1_OID_RSADSI ASN1_OID_ISO_US, ASN1_OID_TRIPLE ( 113549 )
20
+
21
+/** ASN.1 OID for iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) */
22
+#define ASN1_OID_PKCS ASN1_OID_RSADSI, ASN1_OID_SINGLE ( 1 )
23
+
24
+/** ASN.1 OID for iso(1) member-body(2) us(840) rsadsi(113549)
25
+ * digestAlgorithm(2)
26
+ */
27
+#define ASN1_OID_DIGESTALGORITHM ASN1_OID_RSADSI, ASN1_OID_SINGLE ( 2 )
28
+
29
+/** ASN.1 OID for iso(1) identified-organization(3) oiw(14) */
30
+#define ASN1_OID_OIW ASN1_OID_IDENTIFIED_ORGANIZATION, ASN1_OID_SINGLE ( 14 )
31
+
32
+/** ASN.1 OID for iso(1) identified-organization(3) oiw(14) secsig(3) */
33
+#define ASN1_OID_SECSIG ASN1_OID_OIW, ASN1_OID_SINGLE ( 3 )
34
+
35
+/** ASN1. OID for iso(1) identified-organization(3) oiw(14) secsig(3)
36
+ * algorithms(2)
37
+ */
38
+#define ASN1_OID_SECSIG_ALGORITHMS ASN1_OID_SECSIG, ASN1_OID_SINGLE ( 2 )
39
+
40
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840) */
41
+#define ASN1_OID_COUNTRY_US ASN1_OID_COUNTRY, ASN1_OID_DOUBLE ( 840 )
42
+
43
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840) organization(1) */
44
+#define ASN1_OID_US_ORGANIZATION ASN1_OID_COUNTRY_US, ASN1_OID_SINGLE ( 1 )
45
+
46
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840)
47
+ * organization(1) gov(101)
48
+ */
49
+#define ASN1_OID_US_GOV ASN1_OID_US_ORGANIZATION, ASN1_OID_SINGLE ( 101 )
50
+
51
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840)
52
+ * organization(1) gov(101) csor(3)
53
+ */
54
+#define ASN1_OID_CSOR ASN1_OID_US_GOV, ASN1_OID_SINGLE ( 3 )
55
+
56
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840)
57
+ * organization(1) gov(101) csor(3) nistalgorithm(4)
58
+ */
59
+#define ASN1_OID_NISTALGORITHM ASN1_OID_CSOR, ASN1_OID_SINGLE ( 4 )
60
+
61
+/** ASN.1 OID for joint-iso-itu-t(2) country(16) us(840)
62
+ * organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2)
63
+ */
64
+#define ASN1_OID_HASHALGS ASN1_OID_NISTALGORITHM, ASN1_OID_SINGLE ( 2 )
9
 
65
 
10
-#include "crypto/axtls/crypto.h"
66
+/** ASN.1 OID for pkcs-1 */
67
+#define ASN1_OID_PKCS_1 ASN1_OID_PKCS, ASN1_OID_SINGLE ( 1 )
68
+
69
+/** ASN.1 OID for rsaEncryption */
70
+#define ASN1_OID_RSAENCRYPTION ASN1_OID_PKCS_1, ASN1_OID_SINGLE ( 1 )
71
+
72
+/** ASN.1 OID for md5WithRSAEncryption */
73
+#define ASN1_OID_MD5WITHRSAENCRYPTION ASN1_OID_PKCS_1, ASN1_OID_SINGLE ( 4 )
74
+
75
+/** ASN.1 OID for sha1WithRSAEncryption */
76
+#define ASN1_OID_SHA1WITHRSAENCRYPTION ASN1_OID_PKCS_1, ASN1_OID_SINGLE ( 5 )
77
+
78
+/** ASN.1 OID for sha256WithRSAEncryption */
79
+#define ASN1_OID_SHA256WITHRSAENCRYPTION ASN1_OID_PKCS_1, ASN1_OID_SINGLE ( 11 )
80
+
81
+/** ASN.1 OID for id-md5 */
82
+#define ASN1_OID_MD5 ASN1_OID_DIGESTALGORITHM, ASN1_OID_SINGLE ( 5 )
83
+
84
+/** ASN.1 OID for id-sha1 */
85
+#define ASN1_OID_SHA1 ASN1_OID_SECSIG_ALGORITHMS, ASN1_OID_SINGLE ( 26 )
86
+
87
+/** ASN.1 OID for id-sha256 */
88
+#define ASN1_OID_SHA256 ASN1_OID_HASHALGS, ASN1_OID_SINGLE ( 1 )
89
+
90
+/** RSA digestAlgorithm sequence contents */
91
+#define RSA_DIGESTALGORITHM_CONTENTS( ... )				\
92
+	ASN1_OID, VA_ARG_COUNT ( __VA_ARGS__ ), __VA_ARGS__,		\
93
+	ASN1_NULL, 0x00
94
+
95
+/** RSA digestAlgorithm sequence */
96
+#define RSA_DIGESTALGORITHM( ... )					\
97
+	ASN1_SEQUENCE,							\
98
+	VA_ARG_COUNT ( RSA_DIGESTALGORITHM_CONTENTS ( __VA_ARGS__ ) ),	\
99
+	RSA_DIGESTALGORITHM_CONTENTS ( __VA_ARGS__ )
100
+
101
+/** RSA digest prefix */
102
+#define RSA_DIGEST_PREFIX( digest_size )				\
103
+	ASN1_OCTET_STRING, digest_size
104
+
105
+/** RSA digestInfo prefix */
106
+#define RSA_DIGESTINFO_PREFIX( digest_size, ... )			\
107
+	ASN1_SEQUENCE,							\
108
+	( VA_ARG_COUNT ( RSA_DIGESTALGORITHM ( __VA_ARGS__ ) ) +	\
109
+	  VA_ARG_COUNT ( RSA_DIGEST_PREFIX ( digest_size ) ) +		\
110
+	  digest_size ),						\
111
+	RSA_DIGESTALGORITHM ( __VA_ARGS__ ),				\
112
+	RSA_DIGEST_PREFIX ( digest_size )
113
+
114
+/** An RSA context */
115
+struct rsa_context {
116
+	/** Allocated memory */
117
+	void *dynamic;
118
+	/** Modulus */
119
+	bigint_element_t *modulus0;
120
+	/** Modulus size */
121
+	unsigned int size;
122
+	/** Modulus length */
123
+	size_t max_len;
124
+	/** Exponent */
125
+	bigint_element_t *exponent0;
126
+	/** Exponent size */
127
+	unsigned int exponent_size;
128
+	/** Input buffer */
129
+	bigint_element_t *input0;
130
+	/** Output buffer */
131
+	bigint_element_t *output0;
132
+};
133
+
134
+extern struct pubkey_algorithm rsa_algorithm;
11
 
135
 
12
 #endif /* _IPXE_RSA_H */
136
 #endif /* _IPXE_RSA_H */

Loading…
Cancel
Save