summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/cms/cms_enc.c')
-rw-r--r--src/lib/libcrypto/cms/cms_enc.c324
1 files changed, 162 insertions, 162 deletions
diff --git a/src/lib/libcrypto/cms/cms_enc.c b/src/lib/libcrypto/cms/cms_enc.c
index c8a3d705b5..b019d8e8e0 100644
--- a/src/lib/libcrypto/cms/cms_enc.c
+++ b/src/lib/libcrypto/cms/cms_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cms_enc.c,v 1.12 2019/08/10 16:39:17 jsing Exp $ */ 1/* $OpenBSD: cms_enc.c,v 1.13 2019/08/10 16:42:20 jsing Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project. 4 * project.
@@ -67,192 +67,192 @@
67 67
68BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) 68BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
69{ 69{
70 BIO *b; 70 BIO *b;
71 EVP_CIPHER_CTX *ctx; 71 EVP_CIPHER_CTX *ctx;
72 const EVP_CIPHER *ciph; 72 const EVP_CIPHER *ciph;
73 X509_ALGOR *calg = ec->contentEncryptionAlgorithm; 73 X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
74 unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; 74 unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
75 unsigned char *tkey = NULL; 75 unsigned char *tkey = NULL;
76 size_t tkeylen = 0; 76 size_t tkeylen = 0;
77 77
78 int ok = 0; 78 int ok = 0;
79 79
80 int enc, keep_key = 0; 80 int enc, keep_key = 0;
81 81
82 enc = ec->cipher ? 1 : 0; 82 enc = ec->cipher ? 1 : 0;
83 83
84 b = BIO_new(BIO_f_cipher()); 84 b = BIO_new(BIO_f_cipher());
85 if (b == NULL) { 85 if (b == NULL) {
86 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); 86 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
87 return NULL; 87 return NULL;
88 } 88 }
89 89
90 BIO_get_cipher_ctx(b, &ctx); 90 BIO_get_cipher_ctx(b, &ctx);
91 91
92 if (enc) { 92 if (enc) {
93 ciph = ec->cipher; 93 ciph = ec->cipher;
94 /* 94 /*
95 * If not keeping key set cipher to NULL so subsequent calls decrypt. 95 * If not keeping key set cipher to NULL so subsequent calls decrypt.
96 */ 96 */
97 if (ec->key) 97 if (ec->key)
98 ec->cipher = NULL; 98 ec->cipher = NULL;
99 } else { 99 } else {
100 ciph = EVP_get_cipherbyobj(calg->algorithm); 100 ciph = EVP_get_cipherbyobj(calg->algorithm);
101 101
102 if (!ciph) { 102 if (!ciph) {
103 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); 103 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
104 goto err; 104 goto err;
105 } 105 }
106 } 106 }
107 107
108 if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { 108 if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
109 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 109 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
110 CMS_R_CIPHER_INITIALISATION_ERROR); 110 CMS_R_CIPHER_INITIALISATION_ERROR);
111 goto err; 111 goto err;
112 } 112 }
113 113
114 if (enc) { 114 if (enc) {
115 int ivlen; 115 int ivlen;
116 calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); 116 calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
117 /* Generate a random IV if we need one */ 117 /* Generate a random IV if we need one */
118 ivlen = EVP_CIPHER_CTX_iv_length(ctx); 118 ivlen = EVP_CIPHER_CTX_iv_length(ctx);
119 if (ivlen > 0) { 119 if (ivlen > 0) {
120 if (RAND_bytes(iv, ivlen) <= 0) 120 if (RAND_bytes(iv, ivlen) <= 0)
121 goto err; 121 goto err;
122 piv = iv; 122 piv = iv;
123 } 123 }
124 } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { 124 } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
125 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 125 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
126 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); 126 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
127 goto err; 127 goto err;
128 } 128 }
129 tkeylen = EVP_CIPHER_CTX_key_length(ctx); 129 tkeylen = EVP_CIPHER_CTX_key_length(ctx);
130 /* Generate random session key */ 130 /* Generate random session key */
131 if (!enc || !ec->key) { 131 if (!enc || !ec->key) {
132 tkey = OPENSSL_malloc(tkeylen); 132 tkey = OPENSSL_malloc(tkeylen);
133 if (tkey == NULL) { 133 if (tkey == NULL) {
134 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); 134 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
135 goto err; 135 goto err;
136 } 136 }
137 if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) 137 if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
138 goto err; 138 goto err;
139 } 139 }
140 140
141 if (!ec->key) { 141 if (!ec->key) {
142 ec->key = tkey; 142 ec->key = tkey;
143 ec->keylen = tkeylen; 143 ec->keylen = tkeylen;
144 tkey = NULL; 144 tkey = NULL;
145 if (enc) 145 if (enc)
146 keep_key = 1; 146 keep_key = 1;
147 else 147 else
148 ERR_clear_error(); 148 ERR_clear_error();
149 149
150 } 150 }
151 151
152 if (ec->keylen != tkeylen) { 152 if (ec->keylen != tkeylen) {
153 /* If necessary set key length */ 153 /* If necessary set key length */
154 if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { 154 if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
155 /* 155 /*
156 * Only reveal failure if debugging so we don't leak information 156 * Only reveal failure if debugging so we don't leak information
157 * which may be useful in MMA. 157 * which may be useful in MMA.
158 */ 158 */
159 if (enc || ec->debug) { 159 if (enc || ec->debug) {
160 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 160 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
161 CMS_R_INVALID_KEY_LENGTH); 161 CMS_R_INVALID_KEY_LENGTH);
162 goto err; 162 goto err;
163 } else { 163 } else {
164 /* Use random key */ 164 /* Use random key */
165 OPENSSL_clear_free(ec->key, ec->keylen); 165 OPENSSL_clear_free(ec->key, ec->keylen);
166 ec->key = tkey; 166 ec->key = tkey;
167 ec->keylen = tkeylen; 167 ec->keylen = tkeylen;
168 tkey = NULL; 168 tkey = NULL;
169 ERR_clear_error(); 169 ERR_clear_error();
170 } 170 }
171 } 171 }
172 } 172 }
173 173
174 if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { 174 if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
175 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 175 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
176 CMS_R_CIPHER_INITIALISATION_ERROR); 176 CMS_R_CIPHER_INITIALISATION_ERROR);
177 goto err; 177 goto err;
178 } 178 }
179 if (enc) { 179 if (enc) {
180 calg->parameter = ASN1_TYPE_new(); 180 calg->parameter = ASN1_TYPE_new();
181 if (calg->parameter == NULL) { 181 if (calg->parameter == NULL) {
182 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); 182 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
183 goto err; 183 goto err;
184 } 184 }
185 if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { 185 if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
186 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 186 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
187 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); 187 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
188 goto err; 188 goto err;
189 } 189 }
190 /* If parameter type not set omit parameter */ 190 /* If parameter type not set omit parameter */
191 if (calg->parameter->type == V_ASN1_UNDEF) { 191 if (calg->parameter->type == V_ASN1_UNDEF) {
192 ASN1_TYPE_free(calg->parameter); 192 ASN1_TYPE_free(calg->parameter);
193 calg->parameter = NULL; 193 calg->parameter = NULL;
194 } 194 }
195 } 195 }
196 ok = 1; 196 ok = 1;
197 197
198 err: 198 err:
199 if (!keep_key || !ok) { 199 if (!keep_key || !ok) {
200 OPENSSL_clear_free(ec->key, ec->keylen); 200 OPENSSL_clear_free(ec->key, ec->keylen);
201 ec->key = NULL; 201 ec->key = NULL;
202 } 202 }
203 OPENSSL_clear_free(tkey, tkeylen); 203 OPENSSL_clear_free(tkey, tkeylen);
204 if (ok) 204 if (ok)
205 return b; 205 return b;
206 BIO_free(b); 206 BIO_free(b);
207 return NULL; 207 return NULL;
208} 208}
209 209
210int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 210int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
211 const EVP_CIPHER *cipher, 211 const EVP_CIPHER *cipher,
212 const unsigned char *key, size_t keylen) 212 const unsigned char *key, size_t keylen)
213{ 213{
214 ec->cipher = cipher; 214 ec->cipher = cipher;
215 if (key) { 215 if (key) {
216 if ((ec->key = OPENSSL_malloc(keylen)) == NULL) { 216 if ((ec->key = OPENSSL_malloc(keylen)) == NULL) {
217 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT, ERR_R_MALLOC_FAILURE); 217 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT, ERR_R_MALLOC_FAILURE);
218 return 0; 218 return 0;
219 } 219 }
220 memcpy(ec->key, key, keylen); 220 memcpy(ec->key, key, keylen);
221 } 221 }
222 ec->keylen = keylen; 222 ec->keylen = keylen;
223 if (cipher) 223 if (cipher)
224 ec->contentType = OBJ_nid2obj(NID_pkcs7_data); 224 ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
225 return 1; 225 return 1;
226} 226}
227 227
228int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, 228int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
229 const unsigned char *key, size_t keylen) 229 const unsigned char *key, size_t keylen)
230{ 230{
231 CMS_EncryptedContentInfo *ec; 231 CMS_EncryptedContentInfo *ec;
232 if (!key || !keylen) { 232 if (!key || !keylen) {
233 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); 233 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
234 return 0; 234 return 0;
235 } 235 }
236 if (ciph) { 236 if (ciph) {
237 cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); 237 cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
238 if (!cms->d.encryptedData) { 238 if (!cms->d.encryptedData) {
239 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE); 239 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE);
240 return 0; 240 return 0;
241 } 241 }
242 cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); 242 cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
243 cms->d.encryptedData->version = 0; 243 cms->d.encryptedData->version = 0;
244 } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { 244 } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) {
245 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA); 245 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA);
246 return 0; 246 return 0;
247 } 247 }
248 ec = cms->d.encryptedData->encryptedContentInfo; 248 ec = cms->d.encryptedData->encryptedContentInfo;
249 return cms_EncryptedContent_init(ec, ciph, key, keylen); 249 return cms_EncryptedContent_init(ec, ciph, key, keylen);
250} 250}
251 251
252BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) 252BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
253{ 253{
254 CMS_EncryptedData *enc = cms->d.encryptedData; 254 CMS_EncryptedData *enc = cms->d.encryptedData;
255 if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) 255 if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
256 enc->version = 2; 256 enc->version = 2;
257 return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); 257 return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
258} 258}