You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rsa.c 19KB

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