cms_pwri.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /* crypto/cms/cms_pwri.c */
  2. /*
  3. * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  4. * project.
  5. */
  6. /* ====================================================================
  7. * Copyright (c) 2009 The OpenSSL Project. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in
  18. * the documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * 3. All advertising materials mentioning features or use of this
  22. * software must display the following acknowledgment:
  23. * "This product includes software developed by the OpenSSL Project
  24. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  25. *
  26. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  27. * endorse or promote products derived from this software without
  28. * prior written permission. For written permission, please contact
  29. * licensing@OpenSSL.org.
  30. *
  31. * 5. Products derived from this software may not be called "OpenSSL"
  32. * nor may "OpenSSL" appear in their names without prior written
  33. * permission of the OpenSSL Project.
  34. *
  35. * 6. Redistributions of any form whatsoever must retain the following
  36. * acknowledgment:
  37. * "This product includes software developed by the OpenSSL Project
  38. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  41. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  43. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  44. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  45. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  46. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  49. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  50. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  51. * OF THE POSSIBILITY OF SUCH DAMAGE.
  52. * ====================================================================
  53. */
  54. #include "cryptlib.h"
  55. #include <openssl/asn1t.h>
  56. #include <openssl/pem.h>
  57. #include <openssl/x509v3.h>
  58. #include <openssl/err.h>
  59. #include <openssl/cms.h>
  60. #include <openssl/rand.h>
  61. #include <openssl/aes.h>
  62. #include "cms_lcl.h"
  63. #include "asn1_locl.h"
  64. int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
  65. unsigned char *pass, ossl_ssize_t passlen)
  66. {
  67. CMS_PasswordRecipientInfo *pwri;
  68. if (ri->type != CMS_RECIPINFO_PASS) {
  69. CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
  70. return 0;
  71. }
  72. pwri = ri->d.pwri;
  73. pwri->pass = pass;
  74. if (pass && passlen < 0)
  75. passlen = strlen((char *)pass);
  76. pwri->passlen = passlen;
  77. return 1;
  78. }
  79. CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
  80. int iter, int wrap_nid,
  81. int pbe_nid,
  82. unsigned char *pass,
  83. ossl_ssize_t passlen,
  84. const EVP_CIPHER *kekciph)
  85. {
  86. CMS_RecipientInfo *ri = NULL;
  87. CMS_EnvelopedData *env;
  88. CMS_PasswordRecipientInfo *pwri;
  89. EVP_CIPHER_CTX ctx;
  90. X509_ALGOR *encalg = NULL;
  91. unsigned char iv[EVP_MAX_IV_LENGTH];
  92. int ivlen;
  93. env = cms_get0_enveloped(cms);
  94. if (!env)
  95. return NULL;
  96. if (wrap_nid <= 0)
  97. wrap_nid = NID_id_alg_PWRI_KEK;
  98. if (pbe_nid <= 0)
  99. pbe_nid = NID_id_pbkdf2;
  100. /* Get from enveloped data */
  101. if (kekciph == NULL)
  102. kekciph = env->encryptedContentInfo->cipher;
  103. if (kekciph == NULL) {
  104. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
  105. return NULL;
  106. }
  107. if (wrap_nid != NID_id_alg_PWRI_KEK) {
  108. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
  109. CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
  110. return NULL;
  111. }
  112. /* Setup algorithm identifier for cipher */
  113. encalg = X509_ALGOR_new();
  114. if (encalg == NULL) {
  115. goto merr;
  116. }
  117. EVP_CIPHER_CTX_init(&ctx);
  118. if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) {
  119. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
  120. goto err;
  121. }
  122. ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
  123. if (ivlen > 0) {
  124. if (RAND_bytes(iv, ivlen) <= 0)
  125. goto err;
  126. if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) {
  127. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
  128. goto err;
  129. }
  130. encalg->parameter = ASN1_TYPE_new();
  131. if (!encalg->parameter) {
  132. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
  133. goto err;
  134. }
  135. if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) {
  136. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
  137. CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
  138. goto err;
  139. }
  140. }
  141. encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));
  142. EVP_CIPHER_CTX_cleanup(&ctx);
  143. /* Initialize recipient info */
  144. ri = M_ASN1_new_of(CMS_RecipientInfo);
  145. if (!ri)
  146. goto merr;
  147. ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
  148. if (!ri->d.pwri)
  149. goto merr;
  150. ri->type = CMS_RECIPINFO_PASS;
  151. pwri = ri->d.pwri;
  152. /* Since this is overwritten, free up empty structure already there */
  153. X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
  154. pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
  155. if (!pwri->keyEncryptionAlgorithm)
  156. goto merr;
  157. pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
  158. pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
  159. if (!pwri->keyEncryptionAlgorithm->parameter)
  160. goto merr;
  161. if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
  162. &pwri->keyEncryptionAlgorithm->parameter->
  163. value.sequence))
  164. goto merr;
  165. pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
  166. X509_ALGOR_free(encalg);
  167. encalg = NULL;
  168. /* Setup PBE algorithm */
  169. pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
  170. if (!pwri->keyDerivationAlgorithm)
  171. goto err;
  172. CMS_RecipientInfo_set0_password(ri, pass, passlen);
  173. pwri->version = 0;
  174. if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
  175. goto merr;
  176. return ri;
  177. merr:
  178. CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
  179. err:
  180. EVP_CIPHER_CTX_cleanup(&ctx);
  181. if (ri)
  182. M_ASN1_free_of(ri, CMS_RecipientInfo);
  183. if (encalg)
  184. X509_ALGOR_free(encalg);
  185. return NULL;
  186. }
  187. /*
  188. * This is an implementation of the key wrapping mechanism in RFC3211, at
  189. * some point this should go into EVP.
  190. */
  191. static int kek_unwrap_key(unsigned char *out, size_t *outlen,
  192. const unsigned char *in, size_t inlen,
  193. EVP_CIPHER_CTX *ctx)
  194. {
  195. size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
  196. unsigned char *tmp;
  197. int outl, rv = 0;
  198. if (inlen < 2 * blocklen) {
  199. /* too small */
  200. return 0;
  201. }
  202. if (inlen % blocklen) {
  203. /* Invalid size */
  204. return 0;
  205. }
  206. tmp = OPENSSL_malloc(inlen);
  207. if (!tmp)
  208. return 0;
  209. /* setup IV by decrypting last two blocks */
  210. EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
  211. in + inlen - 2 * blocklen, blocklen * 2);
  212. /*
  213. * Do a decrypt of last decrypted block to set IV to correct value output
  214. * it to start of buffer so we don't corrupt decrypted block this works
  215. * because buffer is at least two block lengths long.
  216. */
  217. EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen);
  218. /* Can now decrypt first n - 1 blocks */
  219. EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);
  220. /* Reset IV to original value */
  221. EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
  222. /* Decrypt again */
  223. EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
  224. /* Check check bytes */
  225. if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
  226. /* Check byte failure */
  227. goto err;
  228. }
  229. if (inlen < (size_t)(tmp[0] - 4)) {
  230. /* Invalid length value */
  231. goto err;
  232. }
  233. *outlen = (size_t)tmp[0];
  234. memcpy(out, tmp + 4, *outlen);
  235. rv = 1;
  236. err:
  237. OPENSSL_cleanse(tmp, inlen);
  238. OPENSSL_free(tmp);
  239. return rv;
  240. }
  241. static int kek_wrap_key(unsigned char *out, size_t *outlen,
  242. const unsigned char *in, size_t inlen,
  243. EVP_CIPHER_CTX *ctx)
  244. {
  245. size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
  246. size_t olen;
  247. int dummy;
  248. /*
  249. * First decide length of output buffer: need header and round up to
  250. * multiple of block length.
  251. */
  252. olen = (inlen + 4 + blocklen - 1) / blocklen;
  253. olen *= blocklen;
  254. if (olen < 2 * blocklen) {
  255. /* Key too small */
  256. return 0;
  257. }
  258. if (inlen > 0xFF) {
  259. /* Key too large */
  260. return 0;
  261. }
  262. if (out) {
  263. /* Set header */
  264. out[0] = (unsigned char)inlen;
  265. out[1] = in[0] ^ 0xFF;
  266. out[2] = in[1] ^ 0xFF;
  267. out[3] = in[2] ^ 0xFF;
  268. memcpy(out + 4, in, inlen);
  269. /* Add random padding to end */
  270. if (olen > inlen + 4
  271. && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
  272. return 0;
  273. /* Encrypt twice */
  274. EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
  275. EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
  276. }
  277. *outlen = olen;
  278. return 1;
  279. }
  280. /* Encrypt/Decrypt content key in PWRI recipient info */
  281. int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
  282. int en_de)
  283. {
  284. CMS_EncryptedContentInfo *ec;
  285. CMS_PasswordRecipientInfo *pwri;
  286. const unsigned char *p = NULL;
  287. int plen;
  288. int r = 0;
  289. X509_ALGOR *algtmp, *kekalg = NULL;
  290. EVP_CIPHER_CTX kekctx;
  291. const EVP_CIPHER *kekcipher;
  292. unsigned char *key = NULL;
  293. size_t keylen;
  294. ec = cms->d.envelopedData->encryptedContentInfo;
  295. pwri = ri->d.pwri;
  296. EVP_CIPHER_CTX_init(&kekctx);
  297. if (!pwri->pass) {
  298. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
  299. return 0;
  300. }
  301. algtmp = pwri->keyEncryptionAlgorithm;
  302. if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
  303. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
  304. CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
  305. return 0;
  306. }
  307. if (algtmp->parameter->type == V_ASN1_SEQUENCE) {
  308. p = algtmp->parameter->value.sequence->data;
  309. plen = algtmp->parameter->value.sequence->length;
  310. kekalg = d2i_X509_ALGOR(NULL, &p, plen);
  311. }
  312. if (kekalg == NULL) {
  313. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
  314. CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
  315. return 0;
  316. }
  317. kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
  318. if (!kekcipher) {
  319. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
  320. goto err;
  321. }
  322. /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
  323. if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
  324. goto err;
  325. EVP_CIPHER_CTX_set_padding(&kekctx, 0);
  326. if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) {
  327. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
  328. CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
  329. goto err;
  330. }
  331. algtmp = pwri->keyDerivationAlgorithm;
  332. /* Finish password based key derivation to setup key in "ctx" */
  333. if (EVP_PBE_CipherInit(algtmp->algorithm,
  334. (char *)pwri->pass, pwri->passlen,
  335. algtmp->parameter, &kekctx, en_de) < 0) {
  336. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
  337. goto err;
  338. }
  339. /* Finally wrap/unwrap the key */
  340. if (en_de) {
  341. if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
  342. goto err;
  343. key = OPENSSL_malloc(keylen);
  344. if (!key)
  345. goto err;
  346. if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
  347. goto err;
  348. pwri->encryptedKey->data = key;
  349. pwri->encryptedKey->length = keylen;
  350. } else {
  351. key = OPENSSL_malloc(pwri->encryptedKey->length);
  352. if (!key) {
  353. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
  354. goto err;
  355. }
  356. if (!kek_unwrap_key(key, &keylen,
  357. pwri->encryptedKey->data,
  358. pwri->encryptedKey->length, &kekctx)) {
  359. CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
  360. goto err;
  361. }
  362. ec->key = key;
  363. ec->keylen = keylen;
  364. }
  365. r = 1;
  366. err:
  367. EVP_CIPHER_CTX_cleanup(&kekctx);
  368. if (!r && key)
  369. OPENSSL_free(key);
  370. X509_ALGOR_free(kekalg);
  371. return r;
  372. }