選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

rsa.c 17KB

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