1 /* lib/crypto/openssl/enc_provider/des3.c
8 #include <openssl/evp.h>
11 #define DES_BLOCK_SIZE 8
13 static krb5_error_code
14 validate(krb5_key key, const krb5_data *ivec,
15 const krb5_data *input, const krb5_data *output)
17 /* key->keyblock.enctype was checked by the caller */
19 if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE)
20 return(KRB5_BAD_KEYSIZE);
21 if ((input->length%DES_BLOCK_SIZE) != 0)
22 return(KRB5_BAD_MSIZE);
23 if (ivec && (ivec->length != 8))
24 return(KRB5_BAD_MSIZE);
25 if (input->length != output->length)
26 return(KRB5_BAD_MSIZE);
31 static krb5_error_code
32 validate_iov(krb5_key key, const krb5_data *ivec,
33 const krb5_crypto_iov *data, size_t num_data)
35 size_t i, input_length;
37 for (i = 0, input_length = 0; i < num_data; i++) {
38 const krb5_crypto_iov *iov = &data[i];
40 input_length += iov->data.length;
43 if (key->keyblock.length != KRB5_MIT_DES3_KEYSIZE)
44 return(KRB5_BAD_KEYSIZE);
45 if ((input_length%DES_BLOCK_SIZE) != 0)
46 return(KRB5_BAD_MSIZE);
47 if (ivec && (ivec->length != 8))
48 return(KRB5_BAD_MSIZE);
53 static krb5_error_code
54 k5_des3_encrypt(krb5_key key, const krb5_data *ivec,
55 const krb5_data *input, krb5_data *output)
57 int ret = 0, tmp_len = 0;
58 unsigned int tmp_buf_len = 0;
59 unsigned char *keybuf = NULL;
60 unsigned char *tmp_buf = NULL;
61 EVP_CIPHER_CTX ciph_ctx;
63 ret = validate(key, ivec, input, output);
67 keybuf=key->keyblock.contents;
68 keybuf[key->keyblock.length] = '\0';
70 tmp_buf_len = output->length * 2;
71 tmp_buf = OPENSSL_malloc(tmp_buf_len);
75 EVP_CIPHER_CTX_init(&ciph_ctx);
77 ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, keybuf,
78 (ivec) ? (unsigned char*)ivec->data : NULL);
80 EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
81 ret = EVP_EncryptUpdate(&ciph_ctx, tmp_buf, &tmp_len,
82 (unsigned char *)input->data, input->length);
83 if (!ret || output->length < (unsigned int)tmp_len) {
84 ret = KRB5_CRYPTO_INTERNAL;
86 output->length = tmp_len;
87 ret = EVP_EncryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len);
91 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
94 memcpy(output->data,tmp_buf, output->length);
96 memset(tmp_buf, 0, tmp_buf_len);
97 OPENSSL_free(tmp_buf);
100 return KRB5_CRYPTO_INTERNAL;
106 static krb5_error_code
107 k5_des3_decrypt(krb5_key key, const krb5_data *ivec,
108 const krb5_data *input, krb5_data *output)
110 int ret = 0, tmp_len = 0;
111 unsigned int tmp_buf_len = 0;
112 unsigned char *keybuf = NULL;
113 unsigned char *tmp_buf = NULL;
114 EVP_CIPHER_CTX ciph_ctx;
116 ret = validate(key, ivec, input, output);
120 keybuf=key->keyblock.contents;
121 keybuf[key->keyblock.length] = '\0';
123 tmp_buf_len = output->length;
124 tmp_buf=OPENSSL_malloc(tmp_buf_len);
128 EVP_CIPHER_CTX_init(&ciph_ctx);
130 ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL, keybuf,
131 (ivec) ? (unsigned char*)ivec->data: NULL);
133 EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
134 ret = EVP_DecryptUpdate(&ciph_ctx, tmp_buf, &tmp_len,
135 (unsigned char *)input->data, input->length);
136 if (!ret || output->length < (unsigned int)tmp_len) {
137 ret = KRB5_CRYPTO_INTERNAL;
139 output->length = tmp_len;
140 ret = EVP_DecryptFinal_ex(&ciph_ctx, tmp_buf+tmp_len, &tmp_len);
144 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
147 memcpy(output->data,tmp_buf, output->length);
149 memset(tmp_buf,0,tmp_buf_len);
150 OPENSSL_free(tmp_buf);
153 return KRB5_CRYPTO_INTERNAL;
158 static krb5_error_code
159 k5_des3_encrypt_iov(krb5_key key,
160 const krb5_data *ivec,
161 krb5_crypto_iov *data,
165 int tmp_len = MIT_DES_BLOCK_LENGTH;
166 int oblock_len = MIT_DES_BLOCK_LENGTH*num_data;
167 unsigned char *iblock = NULL, *oblock = NULL;
168 unsigned char *keybuf = NULL;
169 struct iov_block_state input_pos, output_pos;
170 EVP_CIPHER_CTX ciph_ctx;
172 ret = validate_iov(key, ivec, data, num_data);
176 iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH);
179 oblock = OPENSSL_malloc(oblock_len);
181 OPENSSL_free(iblock);
185 IOV_BLOCK_STATE_INIT(&input_pos);
186 IOV_BLOCK_STATE_INIT(&output_pos);
188 keybuf=key->keyblock.contents;
189 keybuf[key->keyblock.length] = '\0';
191 memset(oblock, 0, oblock_len);
193 EVP_CIPHER_CTX_init(&ciph_ctx);
195 ret = EVP_EncryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL,
196 keybuf, (ivec) ? (unsigned char*)ivec->data : NULL);
198 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
199 OPENSSL_free(iblock);
200 OPENSSL_free(oblock);
201 return KRB5_CRYPTO_INTERNAL;
204 EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
208 if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH,
209 data, num_data, &input_pos))
212 if (input_pos.iov_pos == num_data)
215 ret = EVP_EncryptUpdate(&ciph_ctx, oblock, &tmp_len,
216 (unsigned char *)iblock, input_pos.data_pos);
219 krb5int_c_iov_put_block(data, num_data,
220 oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
224 /*if (ivec != NULL && ivec->data)
225 memcpy(ivec->data, oblock, MIT_DES_BLOCK_LENGTH); */
226 ret = EVP_EncryptFinal_ex(&ciph_ctx, oblock+input_pos.data_pos, &tmp_len);
229 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
231 memset(iblock,0,sizeof(iblock));
232 memset(oblock,0,sizeof(oblock));
233 OPENSSL_free(iblock);
234 OPENSSL_free(oblock);
237 return KRB5_CRYPTO_INTERNAL;
241 static krb5_error_code
242 k5_des3_decrypt_iov(krb5_key key,
243 const krb5_data *ivec,
244 krb5_crypto_iov *data,
248 int tmp_len = MIT_DES_BLOCK_LENGTH;
249 int oblock_len = MIT_DES_BLOCK_LENGTH * num_data;
250 unsigned char *iblock = NULL, *oblock = NULL;
251 unsigned char *keybuf = NULL ;
252 struct iov_block_state input_pos, output_pos;
253 EVP_CIPHER_CTX ciph_ctx;
255 ret = validate_iov(key, ivec, data, num_data);
259 iblock = OPENSSL_malloc(MIT_DES_BLOCK_LENGTH);
262 oblock = OPENSSL_malloc(oblock_len);
264 OPENSSL_free(iblock);
268 IOV_BLOCK_STATE_INIT(&input_pos);
269 IOV_BLOCK_STATE_INIT(&output_pos);
271 keybuf=key->keyblock.contents;
272 keybuf[key->keyblock.length] = '\0';
274 memset(oblock, 0, oblock_len);
276 EVP_CIPHER_CTX_init(&ciph_ctx);
278 ret = EVP_DecryptInit_ex(&ciph_ctx, EVP_des_ede3_cbc(), NULL,
279 keybuf, (ivec) ? (unsigned char*)ivec->data : NULL);
281 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
282 OPENSSL_free(iblock);
283 OPENSSL_free(oblock);
284 return KRB5_CRYPTO_INTERNAL;
287 EVP_CIPHER_CTX_set_padding(&ciph_ctx,0);
291 if (!krb5int_c_iov_get_block(iblock, MIT_DES_BLOCK_LENGTH,
292 data, num_data, &input_pos))
295 if (input_pos.iov_pos == num_data)
298 ret = EVP_DecryptUpdate(&ciph_ctx, oblock, &tmp_len,
299 (unsigned char *)iblock, input_pos.data_pos);
302 krb5int_c_iov_put_block(data, num_data,
303 oblock, MIT_DES_BLOCK_LENGTH, &output_pos);
307 /*if (ivec != NULL && ivec->data)
308 memcpy(ivec->data, oblock, MIT_DES_BLOCK_LENGTH); */
309 ret = EVP_DecryptFinal_ex(&ciph_ctx,
310 oblock + input_pos.data_pos, &tmp_len);
313 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
315 memset(iblock,0,sizeof(iblock));
316 memset(oblock,0,sizeof(oblock));
317 OPENSSL_free(iblock);
318 OPENSSL_free(oblock);
321 return KRB5_CRYPTO_INTERNAL;
325 const struct krb5_enc_provider krb5int_enc_des3 = {
327 KRB5_MIT_DES3_KEY_BYTES, KRB5_MIT_DES3_KEYSIZE,
330 krb5int_des3_make_key,
331 krb5int_des_init_state,
332 krb5int_default_free_state,