1 /* $OpenBSD: evp_lib.c,v 1.17 2018/09/12 06:35:38 djm Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #include <stdio.h> 60 #include <string.h> 61 62 #include <openssl/err.h> 63 #include <openssl/evp.h> 64 #include <openssl/objects.h> 65 66 int 67 EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 68 { 69 int ret; 70 71 if (c->cipher->set_asn1_parameters != NULL) 72 ret = c->cipher->set_asn1_parameters(c, type); 73 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) 74 ret = EVP_CIPHER_set_asn1_iv(c, type); 75 else 76 ret = -1; 77 return (ret); 78 } 79 80 int 81 EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 82 { 83 int ret; 84 85 if (c->cipher->get_asn1_parameters != NULL) 86 ret = c->cipher->get_asn1_parameters(c, type); 87 else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) 88 ret = EVP_CIPHER_get_asn1_iv(c, type); 89 else 90 ret = -1; 91 return (ret); 92 } 93 94 int 95 EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 96 { 97 int i = 0; 98 unsigned int l; 99 100 if (type != NULL) { 101 l = EVP_CIPHER_CTX_iv_length(c); 102 if (l > sizeof(c->iv)) { 103 EVPerror(EVP_R_IV_TOO_LARGE); 104 return 0; 105 } 106 i = ASN1_TYPE_get_octetstring(type, c->oiv, l); 107 if (i != (int)l) 108 return (-1); 109 else if (i > 0) 110 memcpy(c->iv, c->oiv, l); 111 } 112 return (i); 113 } 114 115 int 116 EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) 117 { 118 int i = 0; 119 unsigned int j; 120 121 if (type != NULL) { 122 j = EVP_CIPHER_CTX_iv_length(c); 123 if (j > sizeof(c->iv)) { 124 EVPerror(EVP_R_IV_TOO_LARGE); 125 return 0; 126 } 127 i = ASN1_TYPE_set_octetstring(type, c->oiv, j); 128 } 129 return (i); 130 } 131 132 /* Convert the various cipher NIDs and dummies to a proper OID NID */ 133 int 134 EVP_CIPHER_type(const EVP_CIPHER *ctx) 135 { 136 int nid; 137 ASN1_OBJECT *otmp; 138 nid = EVP_CIPHER_nid(ctx); 139 140 switch (nid) { 141 case NID_rc2_cbc: 142 case NID_rc2_64_cbc: 143 case NID_rc2_40_cbc: 144 return NID_rc2_cbc; 145 146 case NID_rc4: 147 case NID_rc4_40: 148 return NID_rc4; 149 150 case NID_aes_128_cfb128: 151 case NID_aes_128_cfb8: 152 case NID_aes_128_cfb1: 153 return NID_aes_128_cfb128; 154 155 case NID_aes_192_cfb128: 156 case NID_aes_192_cfb8: 157 case NID_aes_192_cfb1: 158 return NID_aes_192_cfb128; 159 160 case NID_aes_256_cfb128: 161 case NID_aes_256_cfb8: 162 case NID_aes_256_cfb1: 163 return NID_aes_256_cfb128; 164 165 case NID_des_cfb64: 166 case NID_des_cfb8: 167 case NID_des_cfb1: 168 return NID_des_cfb64; 169 170 case NID_des_ede3_cfb64: 171 case NID_des_ede3_cfb8: 172 case NID_des_ede3_cfb1: 173 return NID_des_cfb64; 174 175 default: 176 /* Check it has an OID and it is valid */ 177 otmp = OBJ_nid2obj(nid); 178 if (!otmp || !otmp->data) 179 nid = NID_undef; 180 ASN1_OBJECT_free(otmp); 181 return nid; 182 } 183 } 184 185 int 186 EVP_CIPHER_block_size(const EVP_CIPHER *e) 187 { 188 return e->block_size; 189 } 190 191 int 192 EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) 193 { 194 return ctx->cipher->block_size; 195 } 196 197 int 198 EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, 199 unsigned int inl) 200 { 201 return ctx->cipher->do_cipher(ctx, out, in, inl); 202 } 203 204 const EVP_CIPHER * 205 EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) 206 { 207 return ctx->cipher; 208 } 209 210 int 211 EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx) 212 { 213 return ctx->encrypt; 214 } 215 216 unsigned long 217 EVP_CIPHER_flags(const EVP_CIPHER *cipher) 218 { 219 return cipher->flags; 220 } 221 222 unsigned long 223 EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) 224 { 225 return ctx->cipher->flags; 226 } 227 228 void * 229 EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) 230 { 231 return ctx->app_data; 232 } 233 234 void 235 EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) 236 { 237 ctx->app_data = data; 238 } 239 240 int 241 EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) 242 { 243 return cipher->iv_len; 244 } 245 246 int 247 EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) 248 { 249 return ctx->cipher->iv_len; 250 } 251 252 int 253 EVP_CIPHER_key_length(const EVP_CIPHER *cipher) 254 { 255 return cipher->key_len; 256 } 257 258 int 259 EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) 260 { 261 return ctx->key_len; 262 } 263 264 int 265 EVP_CIPHER_nid(const EVP_CIPHER *cipher) 266 { 267 return cipher->nid; 268 } 269 270 int 271 EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) 272 { 273 return ctx->cipher->nid; 274 } 275 276 int 277 EVP_CIPHER_CTX_get_iv(const EVP_CIPHER_CTX *ctx, unsigned char *iv, size_t len) 278 { 279 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) 280 return 0; 281 if (len > EVP_MAX_IV_LENGTH) 282 return 0; /* sanity check; shouldn't happen */ 283 /* 284 * Skip the memcpy entirely when the requested IV length is zero, 285 * since the iv pointer may be NULL or invalid. 286 */ 287 if (len != 0) { 288 if (iv == NULL) 289 return 0; 290 memcpy(iv, ctx->iv, len); 291 } 292 return 1; 293 } 294 295 int 296 EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len) 297 { 298 if (ctx == NULL || len != EVP_CIPHER_CTX_iv_length(ctx)) 299 return 0; 300 if (len > EVP_MAX_IV_LENGTH) 301 return 0; /* sanity check; shouldn't happen */ 302 /* 303 * Skip the memcpy entirely when the requested IV length is zero, 304 * since the iv pointer may be NULL or invalid. 305 */ 306 if (len != 0) { 307 if (iv == NULL) 308 return 0; 309 memcpy(ctx->iv, iv, len); 310 } 311 return 1; 312 } 313 314 int 315 EVP_MD_block_size(const EVP_MD *md) 316 { 317 return md->block_size; 318 } 319 320 int 321 EVP_MD_type(const EVP_MD *md) 322 { 323 return md->type; 324 } 325 326 int 327 EVP_MD_pkey_type(const EVP_MD *md) 328 { 329 return md->pkey_type; 330 } 331 332 int 333 EVP_MD_size(const EVP_MD *md) 334 { 335 if (!md) { 336 EVPerror(EVP_R_MESSAGE_DIGEST_IS_NULL); 337 return -1; 338 } 339 return md->md_size; 340 } 341 342 unsigned long 343 EVP_MD_flags(const EVP_MD *md) 344 { 345 return md->flags; 346 } 347 348 const EVP_MD * 349 EVP_MD_CTX_md(const EVP_MD_CTX *ctx) 350 { 351 if (!ctx) 352 return NULL; 353 return ctx->digest; 354 } 355 356 void 357 EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) 358 { 359 ctx->flags |= flags; 360 } 361 362 void 363 EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) 364 { 365 ctx->flags &= ~flags; 366 } 367 368 int 369 EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) 370 { 371 return (ctx->flags & flags); 372 } 373 374 void 375 EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) 376 { 377 ctx->flags |= flags; 378 } 379 380 void 381 EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) 382 { 383 ctx->flags &= ~flags; 384 } 385 386 int 387 EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) 388 { 389 return (ctx->flags & flags); 390 } 391