/* * Encrypt/Decrypt a buffer based on password and algor, result in a * OPENSSL_malloc'ed buffer */ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, const char *pass, int passlen, const unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de) { unsigned char *out = NULL; int outlen, i; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* Decrypt data */ if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, algor->parameter, ctx, en_de)) { PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); goto err; } if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx))) == NULL) { PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) { OPENSSL_free(out); out = NULL; PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB); goto err; } outlen = i; if (!EVP_CipherFinal_ex(ctx, out + i, &i)) { OPENSSL_free(out); out = NULL; PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, PKCS12_R_PKCS12_CIPHERFINAL_ERROR); goto err; } outlen += i; if (datalen) *datalen = outlen; if (data) *data = out; err: EVP_CIPHER_CTX_free(ctx); return out; }
/* //////////////////////////// PRIVATE/PROTECTED //////////////////////////////////// */ OsStatus OsEncryption::init(Direction direction) { OsStatus retval = OS_FAILED; #if defined(OSENCRYPTION) release(); if (mKeyLen > 0 && mKey != NULL && mDataLen > 0 && mData != NULL) { ERR_clear_error(); SSLeay_add_all_algorithms(); mAlgorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC, PKCS5_DEFAULT_ITER, mSalt, mSaltLen); if (mAlgorithm != NULL) { EVP_CIPHER_CTX_init(&(mContext)); if (EVP_PBE_CipherInit(mAlgorithm->algorithm, (const char *)mKey, mKeyLen, mAlgorithm->parameter, &(mContext), (int)direction)) { int blockSize = EVP_CIPHER_CTX_block_size(&mContext); int allocLen = mDataLen + mHeaderLen + blockSize + 1; // plus 1 for null terminator on decrypt mResults = (unsigned char *)OPENSSL_malloc(allocLen); if (mResults == NULL) { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not allocate cryption buffer(size=%d)", allocLen); } else { retval = OS_SUCCESS; } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cipher"); } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "Could not initialize cryption algorithm"); } } else { OsSysLog::add(FAC_AUTH, PRI_ERR, "No encryption key(%d) or data(%d) set.\n", mKeyLen, mDataLen); } #endif return retval; }
unsigned char * PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, int passlen, unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de) { unsigned char *out; int outlen, i; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); /* Decrypt data */ if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, algor->parameter, &ctx, en_de)) { out = NULL; PKCS12error(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); goto err; } if (!(out = malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { PKCS12error(ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) { free(out); out = NULL; PKCS12error(ERR_R_EVP_LIB); goto err; } outlen = i; if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) { free(out); out = NULL; PKCS12error(PKCS12_R_PKCS12_CIPHERFINAL_ERROR); goto err; } outlen += i; if (datalen) *datalen = outlen; if (data) *data = out; err: EVP_CIPHER_CTX_cleanup(&ctx); return out; }
int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, int en_de) { CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; const unsigned char *p = NULL; int plen; int r = 0; X509_ALGOR *algtmp, *kekalg = NULL; EVP_CIPHER_CTX kekctx; const EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; ec = cms->d.envelopedData->encryptedContentInfo; pwri = ri->d.pwri; EVP_CIPHER_CTX_init(&kekctx); if (!pwri->pass) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); return 0; } algtmp = pwri->keyEncryptionAlgorithm; if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); return 0; } if (algtmp->parameter->type == V_ASN1_SEQUENCE) { p = algtmp->parameter->value.sequence->data; plen = algtmp->parameter->value.sequence->length; kekalg = d2i_X509_ALGOR(NULL, &p, plen); } if (kekalg == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); return 0; } kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); if (!kekcipher) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) goto err; EVP_CIPHER_CTX_set_padding(&kekctx, 0); if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } algtmp = pwri->keyDerivationAlgorithm; /* Finish password based key derivation to setup key in "ctx" */ if (EVP_PBE_CipherInit(algtmp->algorithm, (char *)pwri->pass, pwri->passlen, algtmp->parameter, &kekctx, en_de) < 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); goto err; } /* Finally wrap/unwrap the key */ if (en_de) { if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) goto err; key = malloc(keylen); if (!key) goto err; if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) goto err; pwri->encryptedKey->data = key; pwri->encryptedKey->length = keylen; } else { key = malloc(pwri->encryptedKey->length); if (!key) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, pwri->encryptedKey->length, &kekctx)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); goto err; } ec->key = key; ec->keylen = keylen; } r = 1; err: EVP_CIPHER_CTX_cleanup(&kekctx); if (!r && key) free(key); X509_ALGOR_free(kekalg); return r; }