cms_pwri.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /*
  2. * Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "internal/cryptlib.h"
  10. #include <openssl/asn1t.h>
  11. #include <openssl/pem.h>
  12. #include <openssl/x509v3.h>
  13. #include <openssl/err.h>
  14. #include <openssl/cms.h>
  15. #include <openssl/rand.h>
  16. #include <openssl/aes.h>
  17. #include "internal/sizes.h"
  18. #include "crypto/asn1.h"
  19. #include "cms_local.h"
  20. int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
  21. unsigned char *pass, ossl_ssize_t passlen)
  22. {
  23. CMS_PasswordRecipientInfo *pwri;
  24. if (ri->type != CMS_RECIPINFO_PASS) {
  25. ERR_raise(ERR_LIB_CMS, CMS_R_NOT_PWRI);
  26. return 0;
  27. }
  28. pwri = ri->d.pwri;
  29. pwri->pass = pass;
  30. if (pass && passlen < 0)
  31. passlen = strlen((char *)pass);
  32. pwri->passlen = passlen;
  33. return 1;
  34. }
  35. CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
  36. int iter, int wrap_nid,
  37. int pbe_nid,
  38. unsigned char *pass,
  39. ossl_ssize_t passlen,
  40. const EVP_CIPHER *kekciph)
  41. {
  42. STACK_OF(CMS_RecipientInfo) *ris;
  43. CMS_RecipientInfo *ri = NULL;
  44. CMS_EncryptedContentInfo *ec;
  45. CMS_PasswordRecipientInfo *pwri;
  46. EVP_CIPHER_CTX *ctx = NULL;
  47. X509_ALGOR *encalg = NULL;
  48. unsigned char iv[EVP_MAX_IV_LENGTH];
  49. int ivlen;
  50. const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
  51. ec = ossl_cms_get0_env_enc_content(cms);
  52. if (ec == NULL)
  53. return NULL;
  54. ris = CMS_get0_RecipientInfos(cms);
  55. if (ris == NULL)
  56. return NULL;
  57. if (wrap_nid <= 0)
  58. wrap_nid = NID_id_alg_PWRI_KEK;
  59. if (pbe_nid <= 0)
  60. pbe_nid = NID_id_pbkdf2;
  61. /* Get from enveloped data */
  62. if (kekciph == NULL)
  63. kekciph = ec->cipher;
  64. if (kekciph == NULL) {
  65. ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER);
  66. return NULL;
  67. }
  68. if (wrap_nid != NID_id_alg_PWRI_KEK) {
  69. ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
  70. return NULL;
  71. }
  72. /* Setup algorithm identifier for cipher */
  73. encalg = X509_ALGOR_new();
  74. if (encalg == NULL) {
  75. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  76. goto err;
  77. }
  78. ctx = EVP_CIPHER_CTX_new();
  79. if (ctx == NULL) {
  80. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  81. goto err;
  82. }
  83. if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) {
  84. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  85. goto err;
  86. }
  87. ivlen = EVP_CIPHER_CTX_get_iv_length(ctx);
  88. if (ivlen < 0) {
  89. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  90. goto err;
  91. }
  92. if (ivlen > 0) {
  93. if (RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), iv, ivlen, 0) <= 0)
  94. goto err;
  95. if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
  96. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  97. goto err;
  98. }
  99. encalg->parameter = ASN1_TYPE_new();
  100. if (!encalg->parameter) {
  101. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  102. goto err;
  103. }
  104. if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
  105. ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
  106. goto err;
  107. }
  108. }
  109. encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_get_type(ctx));
  110. EVP_CIPHER_CTX_free(ctx);
  111. ctx = NULL;
  112. /* Initialize recipient info */
  113. ri = M_ASN1_new_of(CMS_RecipientInfo);
  114. if (ri == NULL) {
  115. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  116. goto err;
  117. }
  118. ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
  119. if (ri->d.pwri == NULL) {
  120. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  121. goto err;
  122. }
  123. ri->type = CMS_RECIPINFO_PASS;
  124. pwri = ri->d.pwri;
  125. pwri->cms_ctx = cms_ctx;
  126. /* Since this is overwritten, free up empty structure already there */
  127. X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
  128. pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
  129. if (pwri->keyEncryptionAlgorithm == NULL) {
  130. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  131. goto err;
  132. }
  133. pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
  134. pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
  135. if (pwri->keyEncryptionAlgorithm->parameter == NULL) {
  136. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  137. goto err;
  138. }
  139. if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
  140. &pwri->keyEncryptionAlgorithm->parameter->
  141. value.sequence)) {
  142. ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
  143. goto err;
  144. }
  145. pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
  146. X509_ALGOR_free(encalg);
  147. encalg = NULL;
  148. /* Setup PBE algorithm */
  149. pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set_ex(iter, NULL, 0, -1, -1,
  150. cms_ctx->libctx);
  151. if (pwri->keyDerivationAlgorithm == NULL)
  152. goto err;
  153. CMS_RecipientInfo_set0_password(ri, pass, passlen);
  154. pwri->version = 0;
  155. if (!sk_CMS_RecipientInfo_push(ris, ri)) {
  156. ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
  157. goto err;
  158. }
  159. return ri;
  160. err:
  161. EVP_CIPHER_CTX_free(ctx);
  162. if (ri)
  163. M_ASN1_free_of(ri, CMS_RecipientInfo);
  164. X509_ALGOR_free(encalg);
  165. return NULL;
  166. }
  167. /*
  168. * This is an implementation of the key wrapping mechanism in RFC3211, at
  169. * some point this should go into EVP.
  170. */
  171. static int kek_unwrap_key(unsigned char *out, size_t *outlen,
  172. const unsigned char *in, size_t inlen,
  173. EVP_CIPHER_CTX *ctx)
  174. {
  175. size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
  176. unsigned char *tmp;
  177. int outl, rv = 0;
  178. if (blocklen == 0)
  179. return 0;
  180. if (inlen < 2 * blocklen) {
  181. /* too small */
  182. return 0;
  183. }
  184. if (inlen % blocklen) {
  185. /* Invalid size */
  186. return 0;
  187. }
  188. if ((tmp = OPENSSL_malloc(inlen)) == NULL)
  189. return 0;
  190. /* setup IV by decrypting last two blocks */
  191. if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
  192. in + inlen - 2 * blocklen, blocklen * 2)
  193. /*
  194. * Do a decrypt of last decrypted block to set IV to correct value
  195. * output it to start of buffer so we don't corrupt decrypted block
  196. * this works because buffer is at least two block lengths long.
  197. */
  198. || !EVP_DecryptUpdate(ctx, tmp, &outl,
  199. tmp + inlen - blocklen, blocklen)
  200. /* Can now decrypt first n - 1 blocks */
  201. || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
  202. /* Reset IV to original value */
  203. || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
  204. /* Decrypt again */
  205. || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
  206. goto err;
  207. /* Check check bytes */
  208. if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
  209. /* Check byte failure */
  210. goto err;
  211. }
  212. if (inlen < 4 + (size_t)tmp[0]) {
  213. /* Invalid length value */
  214. goto err;
  215. }
  216. *outlen = (size_t)tmp[0];
  217. memcpy(out, tmp + 4, *outlen);
  218. rv = 1;
  219. err:
  220. OPENSSL_clear_free(tmp, inlen);
  221. return rv;
  222. }
  223. static int kek_wrap_key(unsigned char *out, size_t *outlen,
  224. const unsigned char *in, size_t inlen,
  225. EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx)
  226. {
  227. size_t blocklen = EVP_CIPHER_CTX_get_block_size(ctx);
  228. size_t olen;
  229. int dummy;
  230. if (blocklen == 0)
  231. return 0;
  232. /*
  233. * First decide length of output buffer: need header and round up to
  234. * multiple of block length.
  235. */
  236. olen = (inlen + 4 + blocklen - 1) / blocklen;
  237. olen *= blocklen;
  238. if (olen < 2 * blocklen) {
  239. /* Key too small */
  240. return 0;
  241. }
  242. if (inlen > 0xFF) {
  243. /* Key too large */
  244. return 0;
  245. }
  246. if (out) {
  247. /* Set header */
  248. out[0] = (unsigned char)inlen;
  249. out[1] = in[0] ^ 0xFF;
  250. out[2] = in[1] ^ 0xFF;
  251. out[3] = in[2] ^ 0xFF;
  252. memcpy(out + 4, in, inlen);
  253. /* Add random padding to end */
  254. if (olen > inlen + 4
  255. && RAND_bytes_ex(ossl_cms_ctx_get0_libctx(cms_ctx), out + 4 + inlen,
  256. olen - 4 - inlen, 0) <= 0)
  257. return 0;
  258. /* Encrypt twice */
  259. if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
  260. || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
  261. return 0;
  262. }
  263. *outlen = olen;
  264. return 1;
  265. }
  266. /* Encrypt/Decrypt content key in PWRI recipient info */
  267. int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms,
  268. CMS_RecipientInfo *ri, int en_de)
  269. {
  270. CMS_EncryptedContentInfo *ec;
  271. CMS_PasswordRecipientInfo *pwri;
  272. int r = 0;
  273. X509_ALGOR *algtmp, *kekalg = NULL;
  274. EVP_CIPHER_CTX *kekctx = NULL;
  275. char name[OSSL_MAX_NAME_SIZE];
  276. EVP_CIPHER *kekcipher;
  277. unsigned char *key = NULL;
  278. size_t keylen;
  279. const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
  280. ec = ossl_cms_get0_env_enc_content(cms);
  281. pwri = ri->d.pwri;
  282. if (pwri->pass == NULL) {
  283. ERR_raise(ERR_LIB_CMS, CMS_R_NO_PASSWORD);
  284. return 0;
  285. }
  286. algtmp = pwri->keyEncryptionAlgorithm;
  287. if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
  288. ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
  289. return 0;
  290. }
  291. kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
  292. algtmp->parameter);
  293. if (kekalg == NULL) {
  294. ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
  295. return 0;
  296. }
  297. OBJ_obj2txt(name, sizeof(name), kekalg->algorithm, 0);
  298. kekcipher = EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(cms_ctx), name,
  299. ossl_cms_ctx_get0_propq(cms_ctx));
  300. if (kekcipher == NULL) {
  301. ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER);
  302. goto err;
  303. }
  304. kekctx = EVP_CIPHER_CTX_new();
  305. if (kekctx == NULL) {
  306. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  307. goto err;
  308. }
  309. /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
  310. if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
  311. goto err;
  312. EVP_CIPHER_CTX_set_padding(kekctx, 0);
  313. if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) {
  314. ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
  315. goto err;
  316. }
  317. algtmp = pwri->keyDerivationAlgorithm;
  318. /* Finish password based key derivation to setup key in "ctx" */
  319. if (EVP_PBE_CipherInit_ex(algtmp->algorithm,
  320. (char *)pwri->pass, pwri->passlen,
  321. algtmp->parameter, kekctx, en_de,
  322. cms_ctx->libctx, cms_ctx->propq) < 0) {
  323. ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
  324. goto err;
  325. }
  326. /* Finally wrap/unwrap the key */
  327. if (en_de) {
  328. if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
  329. goto err;
  330. key = OPENSSL_malloc(keylen);
  331. if (key == NULL)
  332. goto err;
  333. if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx))
  334. goto err;
  335. pwri->encryptedKey->data = key;
  336. pwri->encryptedKey->length = keylen;
  337. } else {
  338. key = OPENSSL_malloc(pwri->encryptedKey->length);
  339. if (key == NULL)
  340. goto err;
  341. if (!kek_unwrap_key(key, &keylen,
  342. pwri->encryptedKey->data,
  343. pwri->encryptedKey->length, kekctx)) {
  344. ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE);
  345. goto err;
  346. }
  347. OPENSSL_clear_free(ec->key, ec->keylen);
  348. ec->key = key;
  349. ec->keylen = keylen;
  350. }
  351. r = 1;
  352. err:
  353. EVP_CIPHER_free(kekcipher);
  354. EVP_CIPHER_CTX_free(kekctx);
  355. if (!r)
  356. OPENSSL_free(key);
  357. X509_ALGOR_free(kekalg);
  358. return r;
  359. }