cms_pwri.c 11 KB

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