void tr_rc4_set_key (tr_rc4_ctx_t handle, const uint8_t * key, size_t key_length) { assert (handle != NULL); assert (key != NULL); if (!check_result (EVP_CIPHER_CTX_set_key_length (handle, key_length))) return; check_result (EVP_CipherInit_ex (handle, NULL, NULL, key, NULL, -1)); }
void cmd_start_crypt_in(struct ctrl_command *cmd) { #ifdef HAVE_LIBCRYPTO if(in_state.crypt) send_error("can't start decryption - already started!"); if(!in_state.crypt_state.cipher) send_error("can't start decryption - no cipher set!"); if(!in_state.crypt_state.key) send_error("can't start decryption - no key set!"); in_state.crypt = 1; if(!EVP_DecryptInit(&in_state.crypt_state.ctx, in_state.crypt_state.cipher, NULL, NULL)) send_error("can't start decryption - DecryptInit (1) failed: %s!", ERR_error_string(ERR_get_error(), NULL)); /* * XXX - ugly hack to work around OpenSSL bug * if/when OpenSSL fix it, or give proper workaround * use that, and force minimum OpenSSL version * * Without this hack, BF/256 will fail. */ /* cast to avoid warning */ *(unsigned int *) (&in_state.crypt_state.ctx.cipher->flags) |= EVP_CIPH_VARIABLE_LENGTH; if(!EVP_CIPHER_CTX_set_key_length(&in_state.crypt_state.ctx, in_state.crypt_state.keylen)) send_error("can't start decryption - set_key_length failed: %s!", ERR_error_string(ERR_get_error(), NULL)); in_state.crypt_state.ivlen = EVP_CIPHER_CTX_iv_length(&in_state.crypt_state.ctx); if(in_state.crypt_state.ivlen) in_state.crypt_state.iv = calloc(in_state.crypt_state.ivlen, 1); if(in_state.crypt_state.rounds) { if(!EVP_CIPHER_CTX_ctrl(&in_state.crypt_state.ctx, EVP_CTRL_SET_RC5_ROUNDS, in_state.crypt_state.rounds, NULL)) send_error("can't start decryption - SET_RC5_ROUNDS failed: %s!", ERR_error_string(ERR_get_error(), NULL)); } if(!EVP_DecryptInit(&in_state.crypt_state.ctx, NULL, in_state.crypt_state.key, in_state.crypt_state.iv)) send_error("can't start decryption - DecryptInit (2) failed: %s!", ERR_error_string(ERR_get_error(), NULL)); #else send_error("can't start decryption - no OpenSSL support!"); #endif }
/* * call-seq: * cipher.key_length = integer -> integer * * Sets the key length of the cipher. If the cipher is a fixed length cipher then attempting to set the key * length to any value other than the fixed value is an error. * * Under normal circumstances you do not need to call this method (and probably shouldn't). * * See EVP_CIPHER_CTX_set_key_length for further information. */ static VALUE ossl_cipher_set_key_length(VALUE self, VALUE key_length) { int len = NUM2INT(key_length); EVP_CIPHER_CTX *ctx; GetCipher(self, ctx); if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1) ossl_raise(eCipherError, NULL); return key_length; }
void cmd_start_crypt_in(struct ctrl_command *cmd) { #ifdef HAVE_LIBCRYPTO if (in_state.crypt) send_error("can't start decryption - already started!"); if (!in_state.crypt_state.cipher) send_error("can't start decryption - no cipher set!"); if (!in_state.crypt_state.key) send_error("can't start decryption - no key set!"); in_state.crypt = 1; if (!EVP_DecryptInit(&in_state.crypt_state.ctx, in_state.crypt_state.cipher, NULL, NULL)) send_error("can't start decryption - DecryptInit (1) failed: %s!", ERR_error_string(ERR_get_error(), NULL)); if (!EVP_CIPHER_CTX_set_key_length(&in_state.crypt_state.ctx, in_state.crypt_state.keylen)) send_error("can't start decryption - set_key_length failed: %s!", ERR_error_string(ERR_get_error(), NULL)); in_state.crypt_state.ivlen = EVP_CIPHER_CTX_iv_length(&in_state.crypt_state.ctx); if (in_state.crypt_state.ivlen) in_state.crypt_state.iv = calloc(in_state.crypt_state.ivlen, 1); if (in_state.crypt_state.rounds) { if (!EVP_CIPHER_CTX_ctrl(&in_state.crypt_state.ctx, EVP_CTRL_SET_RC5_ROUNDS, in_state.crypt_state.rounds, NULL)) send_error("can't start decryption - SET_RC5_ROUNDS failed: %s!", ERR_error_string(ERR_get_error(), NULL)); } if (!EVP_DecryptInit(&in_state.crypt_state.ctx, NULL, in_state.crypt_state.key, in_state.crypt_state.iv)) send_error("can't start decryption - DecryptInit (2) failed: %s!", ERR_error_string(ERR_get_error(), NULL)); #else send_error("can't start decryption - no OpenSSL support!"); #endif }
void enc_ctx_init(EVP_CIPHER_CTX *ctx, const char *pass, int enc) { unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; int key_len = EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, (unsigned char*) pass, strlen(pass), 1, key, iv); EVP_CIPHER_CTX_init(ctx); EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, enc); if (!EVP_CIPHER_CTX_set_key_length(ctx, key_len)) { LOGE("Invalid key length: %d", key_len); EVP_CIPHER_CTX_cleanup(ctx); exit(EXIT_FAILURE); } EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc); }
int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *ek, int ekl, const unsigned char *iv, EVP_PKEY *priv) { unsigned char *key = NULL; int i, size = 0, ret = 0; if (type) { EVP_CIPHER_CTX_init(ctx); if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) return 0; } if (!priv) return 1; if ((EVP_PKEY_base_id(priv) != EVP_PKEY_RSA) && (EVP_PKEY_base_id(priv) != EVP_PKEY_EC)) { EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA); goto err; } size = EVP_PKEY_size(priv); key = (unsigned char *)OPENSSL_malloc(size + 2); if (key == NULL) { /* ERROR */ EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE); goto err; } i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { /* ERROR */ goto err; } if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) goto err; ret = 1; err: if (key != NULL) OPENSSL_cleanse(key, size); OPENSSL_free(key); return (ret); }
/* * Our hc_EVP_CIPHER init() method; wraps around OpenSSL * EVP_CipherInit_ex(). * * This is very similar to the init() function pointer in an OpenSSL * EVP_CIPHER, but a) we can't access them in 1.1, and b) the method * invocation protocols in hcrypto and OpenSSL are similar but not the * same, thus we must have this wrapper. */ static int cipher_ctx_init(hc_EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) { struct ossl_cipher_ctx *ossl_ctx = ctx->cipher_data; /* EVP_CIPHER_CTX wrapper */ const EVP_CIPHER *c; assert(ossl_ctx != NULL); assert(ctx->cipher != NULL); assert(ctx->cipher->app_data != NULL); /* * Here be dragons. * * We need to make sure that the OpenSSL EVP_CipherInit_ex() is * called with cipher!=NULL just once per EVP_CIPHER_CTX, otherwise * state in the OpenSSL EVP_CIPHER_CTX will get cleaned up and then * we'll segfault. * * hcrypto applications can re-initialize an (hc_)EVP_CIPHER_CTX as * usual by calling (hc)EVP_CipherInit_ex() with a non-NULL cipher * argument, and that will cause cipher_cleanup() (below) to be * called. */ c = ossl_ctx->ossl_cipher = ctx->cipher->app_data; /* OpenSSL's EVP_CIPHER * */ if (!ossl_ctx->initialized) { ossl_ctx->ossl_cipher_ctx = EVP_CIPHER_CTX_new(); if (ossl_ctx->ossl_cipher_ctx == NULL) return 0; /* * So we always call EVP_CipherInit_ex() with c!=NULL, but other * things NULL... */ if (!EVP_CipherInit_ex(ossl_ctx->ossl_cipher_ctx, c, NULL, NULL, NULL, enc)) return 0; ossl_ctx->initialized = 1; } /* ...and from here on always call EVP_CipherInit_ex() with c=NULL */ if ((ctx->cipher->flags & hc_EVP_CIPH_VARIABLE_LENGTH) && ctx->key_len > 0) EVP_CIPHER_CTX_set_key_length(ossl_ctx->ossl_cipher_ctx, ctx->key_len); return EVP_CipherInit_ex(ossl_ctx->ossl_cipher_ctx, NULL, NULL, key, iv, enc); }
int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, const EVP_CIPHER *cipher, ENGINE *impl) { static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; /* All zeros means restart */ if (!key && !cipher && !impl && keylen == 0) { /* Not initialised */ if (ctx->nlast_block == -1) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); ctx->nlast_block = 0; return 1; } /* Initialiase context */ if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) return 0; /* Non-NULL key means initialisation complete */ if (key) { int bl; if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) return 0; if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) return 0; if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) return 0; bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) return 0; make_kn(ctx->k1, ctx->tbl, bl); make_kn(ctx->k2, ctx->k1, bl); OPENSSL_cleanse(ctx->tbl, bl); /* Reset context again ready for first data block */ if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) return 0; /* Zero tbl so resume works */ memset(ctx->tbl, 0, bl); ctx->nlast_block = 0; } return 1; }
void init_cipher(struct encryption_ctx *ctx, const unsigned char *iv, int iv_len, int is_cipher) { ctx->status = STATUS_INIT; if (_method != EncryptionTable) { EVP_CIPHER_CTX_init(ctx->ctx); EVP_CipherInit_ex(ctx->ctx, _cipher, NULL, NULL, NULL, is_cipher); if (!EVP_CIPHER_CTX_set_key_length(ctx->ctx, _key_len)) { cleanup_encryption(ctx); // NSLog(@"Invalid key length"); // assert(0); // TODO free memory and report error return; } EVP_CIPHER_CTX_set_padding(ctx->ctx, 1); EVP_CipherInit_ex(ctx->ctx, NULL, NULL, _key, iv, is_cipher); } }
STDMETHODIMP CBCipher::GenerateKey(short iSize) { if(!m_ctx.cipher)return SetErrorInfo(s_strAlgoError); if(iSize < 0) m_iKeySize = EVP_CIPHER_CTX_key_length(&m_ctx); if(iSize > EVP_MAX_KEY_LENGTH) return E_INVALIDARG; if(!EVP_CIPHER_CTX_set_key_length(&m_ctx, iSize)) return E_INVALIDARG; m_pKey.Allocate(m_iKeySize = iSize); RAND_bytes(m_pKey, m_iKeySize); return S_OK; }
static char * decipher_evp (const unsigned char *key, int keylen, const unsigned char *ciphertext, int cipherlen, const EVP_CIPHER *type, int *outlen, int ivsize) { unsigned char *outbuf; unsigned char *iv = NULL; unsigned long errcode; int outlen2; EVP_CIPHER_CTX a; EVP_CIPHER_CTX_init(&a); EVP_CIPHER_CTX_set_padding(&a, 0); if (ivsize > 0) iv = new_malloc(ivsize); outbuf = new_malloc(cipherlen + 1024); if (ivsize > 0) memcpy(iv, ciphertext, ivsize); EVP_DecryptInit_ex(&a, type, NULL, NULL, iv); EVP_CIPHER_CTX_set_key_length(&a, keylen); EVP_CIPHER_CTX_set_padding(&a, 0); EVP_DecryptInit_ex(&a, NULL, NULL, key, NULL); if (EVP_DecryptUpdate(&a, outbuf, outlen, ciphertext, cipherlen) != 1) yell("EVP_DecryptUpdate died."); if (EVP_DecryptFinal_ex(&a, outbuf + (*outlen), &outlen2) != 1) yell("EVP_DecryptFinal_Ex died."); *outlen += outlen2; EVP_CIPHER_CTX_cleanup(&a); ERR_load_crypto_strings(); while ((errcode = ERR_get_error())) { char r[256]; ERR_error_string_n(errcode, r, 256); yell("ERROR: %s", r); } if (ivsize > 0) new_free(&iv); return outbuf; }
STDMETHODIMP CBCipher::put_Key(VARIANT Val) { if(!m_ctx.cipher)return SetErrorInfo(s_strAlgoError); HRESULT hr; CBVarPtr varPtr; hr = varPtr.Attach(Val); if(FAILED(hr))return hr; if(varPtr.m_nSize > EVP_MAX_KEY_LENGTH) return E_INVALIDARG; if(!EVP_CIPHER_CTX_set_key_length(&m_ctx, m_iKeySize)) return E_INVALIDARG; m_pKey.Allocate(m_iKeySize = varPtr.m_nSize); CopyMemory(m_pKey, varPtr.m_pData, m_iKeySize); return S_OK; }
void cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, const EVP_CIPHER *kt, int enc) { ASSERT(NULL != kt && NULL != ctx); CLEAR (*ctx); EVP_CIPHER_CTX_init (ctx); if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc)) msg (M_SSLERR, "EVP cipher init #1"); #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) msg (M_SSLERR, "EVP set key size"); #endif if (!EVP_CipherInit (ctx, NULL, key, NULL, enc)) msg (M_SSLERR, "EVP cipher init #2"); /* make sure we used a big enough key */ ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= key_len); }
EVP_CIPHER_CTX *enc_setup(int encrypt, const char *encryption_password) { EVP_CIPHER_CTX *ctx=NULL; // Declare enc_iv with individual characters so that the weird last // character can be specified as a hex number in order to prevent // compilation warnings on Macs. uint8_t enc_iv[]={'[', 'l', 'k', 'd', '.', '$', 'G', 0xa3, '\0'}; if(!encryption_password) { logp("No encryption password in %s()\n", __func__); goto error; } if(!(ctx=(EVP_CIPHER_CTX *) calloc_w(1, sizeof(EVP_CIPHER_CTX), __func__))) goto error; // Don't set key or IV because we will modify the parameters. EVP_CIPHER_CTX_init(ctx); if(!(EVP_CipherInit_ex(ctx, EVP_bf_cbc(), NULL, NULL, NULL, encrypt))) { logp("EVP_CipherInit_ex failed\n"); goto error; } EVP_CIPHER_CTX_set_key_length(ctx, strlen(encryption_password)); // We finished modifying parameters so now we can set key and IV if(!EVP_CipherInit_ex(ctx, NULL, NULL, (uint8_t *)encryption_password, enc_iv, encrypt)) { logp("Second EVP_CipherInit_ex failed\n"); goto error; } return ctx; error: free_v((void **)&ctx); return NULL; }
size_t ssl_des3_encrypt(const unsigned char *key, size_t key_len, const unsigned char *input, size_t input_len, const unsigned char *iv, unsigned char **res) { int output_length = 0; EVP_CIPHER_CTX ctx; *res = g_new0(unsigned char, 72); /* Don't set key or IV because we will modify the parameters */ EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, EVP_des_ede3_cbc(), NULL, NULL, NULL, 1); EVP_CIPHER_CTX_set_key_length(&ctx, key_len); EVP_CIPHER_CTX_set_padding(&ctx, 0); /* We finished modifying parameters so now we can set key and IV */ EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, 1); EVP_CipherUpdate(&ctx, *res, &output_length, input, input_len); EVP_CipherFinal_ex(&ctx, *res, &output_length); EVP_CIPHER_CTX_cleanup(&ctx); //EVP_cleanup(); return output_length; }
static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { long num=0; int i=0,l; int key_bits; unsigned char iv[EVP_MAX_IV_LENGTH]; if (type != NULL) { l=EVP_CIPHER_CTX_iv_length(c); i=ASN1_TYPE_get_int_octetstring(type,&num,iv,l); if (i != l) return(-1); key_bits =rc2_magic_to_meth((int)num); if (!key_bits) return(-1); if(i > 0) EVP_CipherInit(c, NULL, NULL, iv, -1); EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); } return(i); }
void cipher_context_init(cipher_ctx_t *evp, int method, int enc) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("cipher_context_init(): Illegal method"); return; } const char *ciphername = supported_ciphers[method]; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) if (cipher == NULL) { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } if (method > RC4) { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) if (cipher == NULL) { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } #endif }
static int gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res) { ossldata *od = c->ptr; int outlen; if (!od->init) { EVP_CIPHER_CTX_init(&od->evp_ctx); if (!EVP_EncryptInit_ex(&od->evp_ctx, od->evp_ciph, NULL, NULL, NULL)) return PXE_CIPHER_INIT; if (!EVP_CIPHER_CTX_set_key_length(&od->evp_ctx, od->klen)) return PXE_CIPHER_INIT; if (!EVP_EncryptInit_ex(&od->evp_ctx, NULL, NULL, od->key, od->iv)) return PXE_CIPHER_INIT; od->init = true; } if (!EVP_EncryptUpdate(&od->evp_ctx, res, &outlen, data, dlen)) return PXE_ERR_GENERIC; return 0; }
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) { BIO *b; EVP_CIPHER_CTX *ctx; const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; size_t tkeylen = 0; int ok = 0; int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; b = BIO_new(BIO_f_cipher()); if (!b) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); return NULL; } BIO_get_cipher_ctx(b, &ctx); if (enc) { ciph = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ if (ec->key) ec->cipher = NULL; } else { ciph = EVP_get_cipherbyobj(calg->algorithm); if (!ciph) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); goto err; } } if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { int ivlen; calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { if (RAND_bytes(iv, ivlen) <= 0) goto err; piv = iv; } } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } tkeylen = EVP_CIPHER_CTX_key_length(ctx); /* Generate random session key */ if (!enc || !ec->key) { tkey = OPENSSL_malloc(tkeylen); if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; } if (!ec->key) { ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; if (enc) keep_key = 1; else ERR_clear_error(); } if (ec->keylen != tkeylen) { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { /* * Only reveal failure if debugging so we don't leak information * which may be useful in MMA. */ if (enc || ec->debug) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_INVALID_KEY_LENGTH); goto err; } else { /* Use random key */ OPENSSL_clear_free(ec->key, ec->keylen); ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; ERR_clear_error(); } } } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (piv) { calg->parameter = ASN1_TYPE_new(); if (!calg->parameter) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } } ok = 1; err: if (!keep_key) { OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; } OPENSSL_clear_free(tkey, tkeylen); if (ok) return b; BIO_free(b); return NULL; }
int ciphers_valid(const char *names) { const Cipher *c; char *cipher_list, *cp; char *p; if (names == NULL || strcmp(names, "") == 0) return 0; cipher_list = cp = xstrdup(names); for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); #ifdef NONE_CIPHER_ENABLED if (c == NULL || (c->number != SSH_CIPHER_SSH2 && c->number != SSH_CIPHER_NONE)) { #else if (c == NULL || (c->number != SSH_CIPHER_SSH2)) { #endif debug("bad cipher %s [%s]", p, names); free(cipher_list); return 0; } } debug3("ciphers ok: [%s]", names); free(cipher_list); return 1; } /* * Parses the name of the cipher. Returns the number of the corresponding * cipher, or -1 on error. */ int cipher_number(const char *name) { const Cipher *c; if (name == NULL) return -1; for (c = ciphers; c->name != NULL; c++) if (strcasecmp(c->name, name) == 0) return c->number; return -1; } char * cipher_name(int id) { const Cipher *c = cipher_by_number(id); return (c==NULL) ? "<unknown>" : c->name; } void cipher_init(CipherContext *cc, const Cipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { static int dowarn = 1; #ifdef SSH_OLD_EVP EVP_CIPHER *type; #else const EVP_CIPHER *type; int klen; #endif u_char *junk, *discard; if (cipher->number == SSH_CIPHER_DES) { if (dowarn) { error("Warning: use of DES is strongly discouraged " "due to cryptographic weaknesses"); dowarn = 0; } if (keylen > 8) keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len) fatal("cipher_init: key length %d is insufficient for %s.", keylen, cipher->name); if (iv != NULL && ivlen < cipher_ivlen(cipher)) fatal("cipher_init: iv length %d is insufficient for %s.", ivlen, cipher->name); cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { chachapoly_init(&cc->cp_ctx, key, keylen); return; } type = (*cipher->evptype)(); EVP_CIPHER_CTX_init(&cc->evp); #ifdef SSH_OLD_EVP if (type->key_len > 0 && type->key_len != keylen) { debug("cipher_init: set keylen (%d -> %d)", type->key_len, keylen); type->key_len = keylen; } EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)); #else if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", cipher->name); if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", cipher->name); klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) fatal("cipher_init: set keylen failed (%d -> %d)", klen, keylen); } if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) fatal("cipher_init: EVP_CipherInit: set key failed for %s", cipher->name); #endif if (cipher->discard_len > 0) { junk = xmalloc(cipher->discard_len); discard = xmalloc(cipher->discard_len); if (EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len) == 0) fatal("evp_crypt: EVP_Cipher failed during discard"); explicit_bzero(discard, cipher->discard_len); free(junk); free(discard); } } /* * cipher_crypt() operates as following: * Copy 'aadlen' bytes (without en/decryption) from 'src' to 'dest'. * Theses bytes are treated as additional authenticated data for * authenticated encryption modes. * En/Decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. * Use 'authlen' bytes at offset 'len'+'aadlen' as the authentication tag. * This tag is written on encryption and verified on decryption. * Both 'aadlen' and 'authlen' can be set to 0. * cipher_crypt() returns 0 on success and -1 if the decryption integrity * check fails. */ int cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, u_int len, u_int aadlen, u_int authlen) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, aadlen, authlen, cc->encrypt); if (authlen) { u_char lastiv[1]; if (authlen != cipher_authlen(cc->cipher)) fatal("%s: authlen mismatch %d", __func__, authlen); /* increment IV */ if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) fatal("%s: EVP_CTRL_GCM_IV_GEN", __func__); /* set tag on decyption */ if (!cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, (u_char *)src + aadlen + len)) fatal("%s: EVP_CTRL_GCM_SET_TAG", __func__); } if (aadlen) { if (authlen && EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) fatal("%s: EVP_Cipher(aad) failed", __func__); memcpy(dest, src, aadlen); } if (len % cc->cipher->block_size) fatal("%s: bad plaintext length %d", __func__, len); if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, len) < 0) fatal("%s: EVP_Cipher failed", __func__); if (authlen) { /* compute tag (on encrypt) or verify tag (on decrypt) */ if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) { if (cc->encrypt) fatal("%s: EVP_Cipher(final) failed", __func__); else return -1; } if (cc->encrypt && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, dest + aadlen + len)) fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); } return 0; } /* Extract the packet length, including any decryption necessary beforehand */ int cipher_get_length(CipherContext *cc, u_int *plenp, u_int seqnr, const u_char *cp, u_int len) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) return chachapoly_get_length(&cc->cp_ctx, plenp, seqnr, cp, len); if (len < 4) return -1; *plenp = get_u32(cp); return 0; } void cipher_cleanup(CipherContext *cc) { if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); } /* * Selects the cipher, and keys if by computing the MD5 checksum of the * passphrase and using the resulting 16 bytes as the key. */ void cipher_set_key_string(CipherContext *cc, const Cipher *cipher, const char *passphrase, int do_encrypt) { u_char digest[16]; if (ssh_digest_memory(SSH_DIGEST_MD5, passphrase, strlen(passphrase), digest, sizeof(digest)) < 0) fatal("%s: md5 failed", __func__); cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); explicit_bzero(digest, sizeof(digest)); }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i, j; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); return NULL; } if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); return NULL; } i = OBJ_obj2nid(p7->type); p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body = PKCS7_get_octet_string(p7->d.sign->contents); if (!PKCS7_is_detached(p7) && data_body == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_SIGNED_DATA_TYPE); goto err; } md_sk = p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; md_sk = p7->d.signed_and_enveloped->md_algs; data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; data_body = p7->d.enveloped->enc_data->enc_data; evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { xa = sk_X509_ALGOR_value(md_sk, i); if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } j = OBJ_obj2nid(xa->algorithm); evp_md = EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp, evp_md); if (out == NULL) out = btmp; else BIO_push(out, btmp); btmp = NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen, ivlen; int max; X509_OBJECT ret; #endif if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; } /* * It was encrypted, we need to decrypt the secret key with the * private key */ /* * Find the recipientInfo which matches the passed certificate (if * any) */ if (pcert) { for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { /* * Always attempt to decrypt all rinfo even after sucess as a * defence against MMA timing attacks. */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } } else { /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) goto err; ERR_clear_error(); } evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) goto err; /* Generate random key as MMA defence */ tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); tkey = OPENSSL_malloc(tkeylen); if (!tkey) goto err; if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) goto err; if (ek == NULL) { ek = tkey; eklen = tkeylen; tkey = NULL; } if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* * Some S/MIME clients don't use the same key and effective key * length. The key length is determined by the size of the * decrypted RSA key. */ if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { /* Use random key as MMA defence */ OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); ek = tkey; eklen = tkeylen; tkey = NULL; } } /* Clear errors so we don't leak information useful in MMA */ ERR_clear_error(); if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) goto err; if (ek) { OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); ek = NULL; } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); OPENSSL_free(tkey); tkey = NULL; } if (out == NULL) out = etmp; else BIO_push(out, etmp); etmp = NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio = in_bio; } else { # if 0 bio = BIO_new(BIO_s_mem()); /* * We need to set this so that when we have read all the data, the * encrypt BIO, if present, will read EOF and encode the last few * bytes */ BIO_set_mem_eof_return(bio, 0); if (data_body->length > 0) BIO_write(bio, (char *)data_body->data, data_body->length); # else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data, data_body->length); else { bio = BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio, 0); } if (bio == NULL) goto err; # endif } BIO_push(out, bio); bio = NULL; #endif if (0) { err: if (ek) { OPENSSL_cleanse(ek, eklen); OPENSSL_free(ek); } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); OPENSSL_free(tkey); } if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out = NULL; } return (out); }
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("cipher_context_init(): Illegal method"); return; } if (method >= SALSA20) { enc_iv_len = supported_ciphers_iv_size[method]; return; } const char *ciphername = supported_ciphers[method]; #if defined(USE_CRYPTO_APPLECC) cipher_cc_t *cc = &ctx->cc; cc->cryptor = NULL; cc->cipher = supported_ciphers_applecc[method]; if (cc->cipher == kCCAlgorithmInvalid) { cc->valid = kCCContextInvalid; } else { cc->valid = kCCContextValid; if (cc->cipher == kCCAlgorithmRC4) { cc->mode = kCCModeRC4; cc->padding = ccNoPadding; } else { cc->mode = kCCModeCFB; cc->padding = ccPKCS7Padding; } return; } #endif cipher_evp_t *evp = &ctx->evp; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) if (cipher == NULL) { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } if (method > RC4_MD5) { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) if (cipher == NULL) { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } #elif defined(USE_CRYPTO_MBEDTLS) // XXX: mbedtls_cipher_setup future change // NOTE: Currently also clears structure. In future versions you will be required to call // mbedtls_cipher_init() on the structure first. // void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); if (cipher == NULL) { LOGE("Cipher %s not found in mbed TLS library", ciphername); FATAL("Cannot initialize mbed TLS cipher"); } mbedtls_cipher_init(evp); if (mbedtls_cipher_setup(evp, cipher) != 0) { FATAL("Cannot initialize mbed TLS cipher context"); } #endif }
ARC4::ARC4(uint8 len) { EVP_CIPHER_CTX_init(&m_ctx); EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL); EVP_CIPHER_CTX_set_key_length(&m_ctx, len); }
static void _wi_cipher_configure_cipher(wi_cipher_t *cipher) { if(cipher->type == WI_CIPHER_BF128) { EVP_CIPHER_CTX_set_key_length(&cipher->encrypt_ctx, 16); EVP_CIPHER_CTX_set_key_length(&cipher->decrypt_ctx, 16); } }
void cipher_init(CipherContext *cc, const Cipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { static int dowarn = 1; const EVP_CIPHER *type; int klen; u_char *junk, *discard; if (cipher->number == SSH_CIPHER_DES) { if (dowarn) { error("Warning: use of DES is strongly discouraged " "due to cryptographic weaknesses"); dowarn = 0; } if (keylen > 8) keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len) fatal("cipher_init: key length %d is insufficient for %s.", keylen, cipher->name); if (iv != NULL && ivlen < cipher_ivlen(cipher)) fatal("cipher_init: iv length %d is insufficient for %s.", ivlen, cipher->name); cc->cipher = cipher; type = (*cipher->evptype)(); EVP_CIPHER_CTX_init(&cc->evp); if (EVP_CipherInit(&cc->evp, type, NULL, __UNCONST(iv), (do_encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", cipher->name); if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, __UNCONST(iv))) fatal("cipher_init: EVP_CTRL_GCM_SET_IV_FIXED failed for %s", cipher->name); klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) fatal("cipher_init: set keylen failed (%d -> %d)", klen, keylen); } if (EVP_CipherInit(&cc->evp, NULL, __UNCONST(key), NULL, -1) == 0) fatal("cipher_init: EVP_CipherInit: set key failed for %s", cipher->name); if (cipher->discard_len > 0) { junk = xmalloc(cipher->discard_len); discard = xmalloc(cipher->discard_len); if (EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len) == 0) fatal("evp_crypt: EVP_Cipher failed during discard"); memset(discard, 0, cipher->discard_len); free(junk); free(discard); } }
/* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { int i,j; BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; unsigned char *tmp=NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body=NULL; const EVP_MD *evp_md; const EVP_CIPHER *evp_cipher=NULL; EVP_CIPHER_CTX *evp_ctx=NULL; X509_ALGOR *enc_alg=NULL; STACK_OF(X509_ALGOR) *md_sk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; X509_ALGOR *xalg=NULL; PKCS7_RECIP_INFO *ri=NULL; i=OBJ_obj2nid(p7->type); p7->state=PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: data_body=PKCS7_get_octet_string(p7->d.sign->contents); md_sk=p7->d.sign->md_algs; break; case NID_pkcs7_signedAndEnveloped: rsk=p7->d.signed_and_enveloped->recipientinfo; md_sk=p7->d.signed_and_enveloped->md_algs; data_body=p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.signed_and_enveloped->enc_data->algorithm; break; case NID_pkcs7_enveloped: rsk=p7->d.enveloped->recipientinfo; enc_alg=p7->d.enveloped->enc_data->algorithm; data_body=p7->d.enveloped->enc_data->enc_data; evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm); if (evp_cipher == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } xalg=p7->d.enveloped->enc_data->algorithm; break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; } /* We will be checking the signature */ if (md_sk != NULL) { for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) { xa=sk_X509_ALGOR_value(md_sk,i); if ((btmp=BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } j=OBJ_obj2nid(xa->algorithm); evp_md=EVP_get_digestbynid(j); if (evp_md == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } BIO_set_md(btmp,evp_md); if (out == NULL) out=btmp; else BIO_push(out,btmp); btmp=NULL; } } if (evp_cipher != NULL) { #if 0 unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char *p; int keylen,ivlen; int max; X509_OBJECT ret; #endif int jj; if ((etmp=BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB); goto err; } /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ if (pcert) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); if (!pkcs7_cmp_ri(ri, pcert)) break; ri=NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); goto err; } } jj=EVP_PKEY_size(pkey); tmp=(unsigned char *)OPENSSL_malloc(jj+10); if (tmp == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE); goto err; } /* If we haven't got a certificate try each ri in turn */ if (pcert == NULL) { for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri=sk_PKCS7_RECIP_INFO_value(rsk,i); jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj > 0) break; ERR_clear_error(); ri = NULL; } if (ri == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_RECIPIENT_MATCHES_KEY); goto err; } } else { jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), M_ASN1_STRING_length(ri->enc_key), pkey); if (jj <= 0) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_EVP_LIB); goto err; } } evp_ctx=NULL; BIO_get_cipher_ctx(etmp,&evp_ctx); if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) goto err; if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { /* Some S/MIME clients don't use the same key * and effective key length. The key length is * determined by the size of the decrypted RSA key. */ if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); goto err; } } if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) goto err; OPENSSL_cleanse(tmp,jj); if (out == NULL) out=etmp; else BIO_push(out,etmp); etmp=NULL; } #if 1 if (PKCS7_is_detached(p7) || (in_bio != NULL)) { bio=in_bio; } else { #if 0 bio=BIO_new(BIO_s_mem()); /* We need to set this so that when we have read all * the data, the encrypt BIO, if present, will read * EOF and encode the last few bytes */ BIO_set_mem_eof_return(bio,0); if (data_body->length > 0) BIO_write(bio,(char *)data_body->data,data_body->length); #else if (data_body->length > 0) bio = BIO_new_mem_buf(data_body->data,data_body->length); else { bio=BIO_new(BIO_s_mem()); BIO_set_mem_eof_return(bio,0); } #endif } BIO_push(out,bio); bio=NULL; #endif if (0) { err: if (out != NULL) BIO_free_all(out); if (btmp != NULL) BIO_free_all(btmp); if (etmp != NULL) BIO_free_all(etmp); if (bio != NULL) BIO_free_all(bio); out=NULL; } if (tmp != NULL) OPENSSL_free(tmp); return(out); }
ARC4::ARC4(uint8 len) : m_ctx() { m_ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(m_ctx, EVP_rc4(), NULL, NULL, NULL); EVP_CIPHER_CTX_set_key_length(m_ctx, len); }
SARC4::SARC4(uint8 len) { EVP_CIPHER_CTX_init(&m_ctx); EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), nullptr, nullptr, nullptr); EVP_CIPHER_CTX_set_key_length(&m_ctx, len); }
int cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { #ifdef WITH_OPENSSL int ret = SSH_ERR_INTERNAL_ERROR; const EVP_CIPHER *type; int klen; u_char *junk, *discard; if (cipher->number == SSH_CIPHER_DES) { if (keylen > 8) keylen = 8; } #endif cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len || (iv != NULL && ivlen < cipher_ivlen(cipher))) return SSH_ERR_INVALID_ARGUMENT; cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { return chachapoly_init(&cc->cp_ctx, key, keylen); } #ifndef WITH_OPENSSL if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); aesctr_ivsetup(&cc->ac_ctx, iv); return 0; } if ((cc->cipher->flags & CFLAG_NONE) != 0) return 0; return SSH_ERR_INVALID_ARGUMENT; #else type = (*cipher->evptype)(); EVP_CIPHER_CTX_init(&cc->evp); if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } klen = EVP_CIPHER_CTX_key_length(&cc->evp); if (klen > 0 && keylen != (u_int)klen) { if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } } if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto bad; } if (cipher->discard_len > 0) { if ((junk = malloc(cipher->discard_len)) == NULL || (discard = malloc(cipher->discard_len)) == NULL) { if (junk != NULL) free(junk); ret = SSH_ERR_ALLOC_FAIL; goto bad; } ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); explicit_bzero(discard, cipher->discard_len); free(junk); free(discard); if (ret != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; bad: EVP_CIPHER_CTX_cleanup(&cc->evp); return ret; } } #endif return 0; }
int cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { struct sshcipher_ctx *cc = NULL; int ret = SSH_ERR_INTERNAL_ERROR; #ifdef WITH_OPENSSL const EVP_CIPHER *type; int klen; u_char *junk, *discard; #endif *ccp = NULL; if ((cc = calloc(sizeof(*cc), 1)) == NULL) return SSH_ERR_ALLOC_FAIL; if (cipher->number == SSH_CIPHER_DES) { if (keylen > 8) keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len || (iv != NULL && ivlen < cipher_ivlen(cipher))) { ret = SSH_ERR_INVALID_ARGUMENT; goto out; } cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ret = chachapoly_init(&cc->cp_ctx, key, keylen); goto out; } #ifndef WITH_OPENSSL if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); aesctr_ivsetup(&cc->ac_ctx, iv); ret = 0; goto out; } if ((cc->cipher->flags & CFLAG_NONE) != 0) { ret = 0; goto out; } ret = SSH_ERR_INVALID_ARGUMENT; goto out; #else /* WITH_OPENSSL */ type = (*cipher->evptype)(); if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (EVP_CipherInit(cc->evp, type, NULL, (const u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (cipher_authlen(cipher) && !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, __UNCONST(iv))) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } klen = EVP_CIPHER_CTX_key_length(cc->evp); if (klen > 0 && keylen != (u_int)klen) { if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } } if (EVP_CipherInit(cc->evp, NULL, __UNCONST(key), NULL, -1) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } if (cipher->discard_len > 0) { if ((junk = malloc(cipher->discard_len)) == NULL || (discard = malloc(cipher->discard_len)) == NULL) { free(junk); ret = SSH_ERR_ALLOC_FAIL; goto out; } ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); explicit_bzero(discard, cipher->discard_len); free(junk); free(discard); if (ret != 1) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } } ret = 0; #endif /* WITH_OPENSSL */ out: if (ret == 0) { /* success */ *ccp = cc; } else { if (cc != NULL) { #ifdef WITH_OPENSSL if (cc->evp != NULL) EVP_CIPHER_CTX_free(cc->evp); #endif /* WITH_OPENSSL */ explicit_bzero(cc, sizeof(*cc)); free(cc); } } return ret; }