void cipher_ctx_init(EVP_CIPHER_CTX *ctx, const uint8_t *key, int key_len, const EVP_CIPHER *kt, int enc) { ASSERT(NULL != kt && NULL != ctx); EVP_CIPHER_CTX_init(ctx); if (!EVP_CipherInit(ctx, kt, NULL, NULL, enc)) { crypto_msg(M_FATAL, "EVP cipher init #1"); } #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length(ctx, key_len)) { crypto_msg(M_FATAL, "EVP set key size"); } #endif if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, enc)) { crypto_msg(M_FATAL, "EVP cipher init #2"); } /* make sure we used a big enough key */ ASSERT(EVP_CIPHER_CTX_key_length(ctx) <= key_len); }
static ENGINE * setup_engine(const char *engine) { ENGINE *e = NULL; ENGINE_load_builtin_engines(); if (engine) { if (strcmp(engine, "auto") == 0) { msg(M_INFO, "Initializing OpenSSL auto engine support"); ENGINE_register_all_complete(); return NULL; } if ((e = ENGINE_by_id(engine)) == NULL && (e = try_load_engine(engine)) == NULL) { crypto_msg(M_FATAL, "OpenSSL error: cannot load engine '%s'", engine); } if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { crypto_msg(M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'", engine); } msg(M_INFO, "Initializing OpenSSL support for engine '%s'", ENGINE_get_id(e)); } return e; }
const EVP_CIPHER * cipher_kt_get(const char *ciphername) { const EVP_CIPHER *cipher = NULL; ASSERT(ciphername); cipher = EVP_get_cipherbyname(ciphername); if (NULL == cipher) { crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername); return NULL; } if (EVP_CIPHER_key_length(cipher) > MAX_CIPHER_KEY_LENGTH) { msg(D_LOW, "Cipher algorithm '%s' uses a default key size (%d bytes) " "which is larger than " PACKAGE_NAME "'s current maximum key size " "(%d bytes)", ciphername, EVP_CIPHER_key_length(cipher), MAX_CIPHER_KEY_LENGTH); return NULL; } return cipher; }
const EVP_MD * md_kt_get (const char *digest) { const EVP_MD *md = NULL; ASSERT (digest); md = EVP_get_digestbyname (digest); if (!md) crypto_msg (M_FATAL, "Message hash algorithm '%s' not found", digest); if (EVP_MD_size (md) > MAX_HMAC_KEY_LENGTH) { crypto_msg (M_FATAL, "Message hash algorithm '%s' uses a default hash " "size (%d bytes) which is larger than " PACKAGE_NAME "'s current " "maximum hash size (%d bytes)", digest, EVP_MD_size (md), MAX_HMAC_KEY_LENGTH); } return md; }
int cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { if (!EVP_CipherUpdate (ctx, dst, dst_len, src, src_len)) crypto_msg(M_FATAL, "%s: EVP_CipherUpdate() failed", __func__); return 1; }
int rand_bytes(uint8_t *output, int len) { if (unlikely(1 != RAND_bytes (output, len))) { crypto_msg(D_CRYPT_ERRORS, "RAND_bytes() failed"); return 0; } return 1; }
int cipher_ctx_update_ad (EVP_CIPHER_CTX *ctx, const uint8_t *src, int src_len) { #ifdef HAVE_AEAD_CIPHER_MODES int len; if (!EVP_CipherUpdate (ctx, NULL, &len, src, src_len)) crypto_msg(M_FATAL, "%s: EVP_CipherUpdate() failed", __func__); return 1; #else ASSERT (0); #endif }
bool crypto_pem_decode(const char *name, struct buffer *dst, const struct buffer *src) { bool ret = false; BIO *bio = BIO_new_mem_buf((char *)BPTR(src), BLEN(src)); if (!bio) { crypto_msg(M_FATAL, "Cannot open memory BIO for PEM decode"); } char *name_read = NULL; char *header_read = NULL; uint8_t *data_read = NULL; long data_read_len = 0; if (!PEM_read_bio(bio, &name_read, &header_read, &data_read, &data_read_len)) { dmsg(D_CRYPT_ERRORS, "%s: PEM decode failed", __func__); goto cleanup; } if (strcmp(name, name_read)) { dmsg(D_CRYPT_ERRORS, "%s: unexpected PEM name (got '%s', expected '%s')", __func__, name_read, name); goto cleanup; } uint8_t *dst_data = buf_write_alloc(dst, data_read_len); if (!dst_data) { dmsg(D_CRYPT_ERRORS, "%s: dst too small (%i, needs %li)", __func__, BCAP(dst), data_read_len); goto cleanup; } memcpy(dst_data, data_read, data_read_len); ret = true; cleanup: OPENSSL_free(name_read); OPENSSL_free(header_read); OPENSSL_free(data_read); if (!BIO_free(bio)) { ret = false;; } return ret; }
bool key_des_check(uint8_t *key, int key_len, int ndc) { int i; struct buffer b; buf_set_read(&b, key, key_len); for (i = 0; i < ndc; ++i) { DES_cblock *dc = (DES_cblock *) buf_read_alloc(&b, sizeof(DES_cblock)); if (!dc) { crypto_msg(D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material"); goto err; } if (DES_is_weak_key(dc)) { crypto_msg(D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected"); goto err; } if (!DES_check_key_parity(dc)) { crypto_msg(D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected"); goto err; } } return true; err: ERR_clear_error(); return false; }