rsa_oaep.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:6k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* crypto/rsa/rsa_oaep.c */
  2. /* Written by Ulf Moeller. This software is distributed on an "AS IS"
  3.    basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */
  4. /* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
  5. /* See Victor Shoup, "OAEP reconsidered," Nov. 2000,
  6.  * <URL: http://www.shoup.net/papers/oaep.ps.Z>
  7.  * for problems with the security proof for the
  8.  * original OAEP scheme, which EME-OAEP is based on.
  9.  * 
  10.  * A new proof can be found in E. Fujisaki, T. Okamoto,
  11.  * D. Pointcheval, J. Stern, "RSA-OEAP is Still Alive!",
  12.  * Dec. 2000, <URL: http://eprint.iacr.org/2000/061/>.
  13.  * The new proof has stronger requirements for the
  14.  * underlying permutation: "partial-one-wayness" instead
  15.  * of one-wayness.  For the RSA function, this is
  16.  * an equivalent notion.
  17.  */
  18. #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
  19. #include <stdio.h>
  20. #include "cryptlib.h"
  21. #include <openssl/bn.h>
  22. #include <openssl/rsa.h>
  23. #include <openssl/evp.h>
  24. #include <openssl/rand.h>
  25. #include <openssl/sha.h>
  26. int MGF1(unsigned char *mask, long len,
  27. const unsigned char *seed, long seedlen);
  28. int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
  29. const unsigned char *from, int flen,
  30. const unsigned char *param, int plen)
  31. {
  32. int i, emlen = tlen - 1;
  33. unsigned char *db, *seed;
  34. unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH];
  35. if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1)
  36. {
  37. RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
  38.    RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
  39. return 0;
  40. }
  41. if (emlen < 2 * SHA_DIGEST_LENGTH + 1)
  42. {
  43. RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
  44. return 0;
  45. }
  46. dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH);
  47. if (dbmask == NULL)
  48. {
  49. RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
  50. return 0;
  51. }
  52. to[0] = 0;
  53. seed = to + 1;
  54. db = to + SHA_DIGEST_LENGTH + 1;
  55. EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL);
  56. memset(db + SHA_DIGEST_LENGTH, 0,
  57. emlen - flen - 2 * SHA_DIGEST_LENGTH - 1);
  58. db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01;
  59. memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int) flen);
  60. if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0)
  61. return 0;
  62. #ifdef PKCS_TESTVECT
  63. memcpy(seed,
  64.    "xaaxfdx12xf6x59xcaxe6x34x89xb4x79xe5x07x6dxdexc2xf0x6cxb5x8f",
  65.    20);
  66. #endif
  67. MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH);
  68. for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++)
  69. db[i] ^= dbmask[i];
  70. MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH);
  71. for (i = 0; i < SHA_DIGEST_LENGTH; i++)
  72. seed[i] ^= seedmask[i];
  73. OPENSSL_free(dbmask);
  74. return 1;
  75. }
  76. int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
  77. const unsigned char *from, int flen, int num,
  78. const unsigned char *param, int plen)
  79. {
  80. int i, dblen, mlen = -1;
  81. const unsigned char *maskeddb;
  82. int lzero;
  83. unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
  84. int bad = 0;
  85. if (--num < 2 * SHA_DIGEST_LENGTH + 1)
  86. /* 'num' is the length of the modulus, i.e. does not depend on the
  87.  * particular ciphertext. */
  88. goto decoding_err;
  89. lzero = num - flen;
  90. if (lzero < 0)
  91. {
  92. /* lzero == -1 */
  93. /* signalling this error immediately after detection might allow
  94.  * for side-channel attacks (e.g. timing if 'plen' is huge
  95.  * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
  96.  * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
  97.  * so we use a 'bad' flag */
  98. bad = 1;
  99. lzero = 0;
  100. }
  101. maskeddb = from - lzero + SHA_DIGEST_LENGTH;
  102. dblen = num - SHA_DIGEST_LENGTH;
  103. db = OPENSSL_malloc(dblen);
  104. if (db == NULL)
  105. {
  106. RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
  107. return -1;
  108. }
  109. MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
  110. for (i = lzero; i < SHA_DIGEST_LENGTH; i++)
  111. seed[i] ^= from[i - lzero];
  112.   
  113. MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
  114. for (i = 0; i < dblen; i++)
  115. db[i] ^= maskeddb[i];
  116. EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
  117. if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
  118. goto decoding_err;
  119. else
  120. {
  121. for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
  122. if (db[i] != 0x00)
  123. break;
  124. if (db[i] != 0x01 || i++ >= dblen)
  125. goto decoding_err;
  126. else
  127. {
  128. /* everything looks OK */
  129. mlen = dblen - i;
  130. if (tlen < mlen)
  131. {
  132. RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
  133. mlen = -1;
  134. }
  135. else
  136. memcpy(to, db + i, mlen);
  137. }
  138. }
  139. OPENSSL_free(db);
  140. return mlen;
  141. decoding_err:
  142. /* to avoid chosen ciphertext attacks, the error message should not reveal
  143.  * which kind of decoding error happened */
  144. RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
  145. if (db != NULL) OPENSSL_free(db);
  146. return -1;
  147. }
  148. int PKCS1_MGF1(unsigned char *mask, long len,
  149. const unsigned char *seed, long seedlen, const EVP_MD *dgst)
  150. {
  151. long i, outlen = 0;
  152. unsigned char cnt[4];
  153. EVP_MD_CTX c;
  154. unsigned char md[EVP_MAX_MD_SIZE];
  155. int mdlen;
  156. EVP_MD_CTX_init(&c);
  157. mdlen = EVP_MD_size(dgst);
  158. for (i = 0; outlen < len; i++)
  159. {
  160. cnt[0] = (unsigned char)((i >> 24) & 255);
  161. cnt[1] = (unsigned char)((i >> 16) & 255);
  162. cnt[2] = (unsigned char)((i >> 8)) & 255;
  163. cnt[3] = (unsigned char)(i & 255);
  164. EVP_DigestInit_ex(&c,dgst, NULL);
  165. EVP_DigestUpdate(&c, seed, seedlen);
  166. EVP_DigestUpdate(&c, cnt, 4);
  167. if (outlen + mdlen <= len)
  168. {
  169. EVP_DigestFinal_ex(&c, mask + outlen, NULL);
  170. outlen += mdlen;
  171. }
  172. else
  173. {
  174. EVP_DigestFinal_ex(&c, md, NULL);
  175. memcpy(mask + outlen, md, len - outlen);
  176. outlen = len;
  177. }
  178. }
  179. EVP_MD_CTX_cleanup(&c);
  180. return 0;
  181. }
  182. int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen)
  183. {
  184. return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1());
  185. }
  186. #endif