📄 evp.c
字号:
ctx->encrypt = (encp ? 1 : 0); if (c && (c != ctx->cipher)) { EVP_CIPHER_CTX_cleanup(ctx); ctx->cipher = c; ctx->key_len = c->key_len; ctx->cipher_data = malloc(c->ctx_size); if (ctx->cipher_data == NULL && c->ctx_size != 0) return 0; } else if (ctx->cipher == NULL) { /* reuse of cipher, but not any cipher ever set! */ return 0; } switch (EVP_CIPHER_CTX_flags(ctx)) { case EVP_CIPH_CBC_MODE: assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv)); if (iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); break; default: return 0; } if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) ctx->cipher->init(ctx, key, iv, encp); return 1;}/** * Encypher/decypher data * * @param ctx the cipher context. * @param out out data from the operation. * @param in in data to the operation. * @param size length of data. * * @return 1 on success. */intEVP_Cipher(EVP_CIPHER_CTX *ctx, void *out, const void *in,size_t size){ return ctx->cipher->do_cipher(ctx, out, in, size);}/* * */static intenc_null_init(EVP_CIPHER_CTX *ctx, const unsigned char * key, const unsigned char * iv, int encp){ return 1;}static intenc_null_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size){ memmove(out, in, size); return 1;}static intenc_null_cleanup(EVP_CIPHER_CTX *ctx){ return 1;}/** * The NULL cipher type, does no encryption/decryption. * * @return the null EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_enc_null(void){ static const EVP_CIPHER enc_null = { 0, 0, 0, 0, EVP_CIPH_CBC_MODE, enc_null_init, enc_null_do_cipher, enc_null_cleanup, 0, NULL, NULL, NULL, NULL }; return &enc_null;}/* * */struct rc2_cbc { unsigned int maximum_effective_key; RC2_KEY key;};static intrc2_init(EVP_CIPHER_CTX *ctx, const unsigned char * key, const unsigned char * iv, int encp){ struct rc2_cbc *k = ctx->cipher_data; k->maximum_effective_key = EVP_CIPHER_CTX_key_length(ctx) * 8; RC2_set_key(&k->key, EVP_CIPHER_CTX_key_length(ctx), key, k->maximum_effective_key); return 1;}static intrc2_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size){ struct rc2_cbc *k = ctx->cipher_data; RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt); return 1;}static intrc2_cleanup(EVP_CIPHER_CTX *ctx){ memset(ctx->cipher_data, 0, sizeof(struct rc2_cbc)); return 1;}/** * The RC2 cipher type * * @return the RC2 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_rc2_cbc(void){ static const EVP_CIPHER rc2_cbc = { 0, RC2_BLOCK_SIZE, RC2_KEY_LENGTH, RC2_BLOCK_SIZE, EVP_CIPH_CBC_MODE, rc2_init, rc2_do_cipher, rc2_cleanup, sizeof(struct rc2_cbc), NULL, NULL, NULL, NULL }; return &rc2_cbc;}/** * The RC2-40 cipher type * * @return the RC2-40 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_rc2_40_cbc(void){ static const EVP_CIPHER rc2_40_cbc = { 0, RC2_BLOCK_SIZE, 5, RC2_BLOCK_SIZE, EVP_CIPH_CBC_MODE, rc2_init, rc2_do_cipher, rc2_cleanup, sizeof(struct rc2_cbc), NULL, NULL, NULL, NULL }; return &rc2_40_cbc;}/** * The RC2-64 cipher type * * @return the RC2-64 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_rc2_64_cbc(void){ static const EVP_CIPHER rc2_64_cbc = { 0, RC2_BLOCK_SIZE, 8, RC2_BLOCK_SIZE, EVP_CIPH_CBC_MODE, rc2_init, rc2_do_cipher, rc2_cleanup, sizeof(struct rc2_cbc), NULL, NULL, NULL, NULL }; return &rc2_64_cbc;}/** * The RC4 cipher type * * @return the RC4 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_rc4(void){ printf("evp rc4\n"); abort(); return NULL;}/** * The RC4-40 cipher type * * @return the RC4-40 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_rc4_40(void){ printf("evp rc4_40\n"); abort(); return NULL;}/* * */struct des_ede3_cbc { DES_key_schedule ks[3];};static intdes_ede3_cbc_init(EVP_CIPHER_CTX *ctx, const unsigned char * key, const unsigned char * iv, int encp){ struct des_ede3_cbc *k = ctx->cipher_data; DES_key_sched((DES_cblock *)(key), &k->ks[0]); DES_key_sched((DES_cblock *)(key + 8), &k->ks[1]); DES_key_sched((DES_cblock *)(key + 16), &k->ks[2]); return 1;}static intdes_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size){ struct des_ede3_cbc *k = ctx->cipher_data; DES_ede3_cbc_encrypt(in, out, size, &k->ks[0], &k->ks[1], &k->ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); return 1;}static intdes_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx){ memset(ctx->cipher_data, 0, sizeof(struct des_ede3_cbc)); return 1;}/** * The tripple DES cipher type * * @return the DES-EDE3-CBC EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_des_ede3_cbc(void){ static const EVP_CIPHER des_ede3_cbc = { 0, 8, 24, 8, EVP_CIPH_CBC_MODE, des_ede3_cbc_init, des_ede3_cbc_do_cipher, des_ede3_cbc_cleanup, sizeof(struct des_ede3_cbc), NULL, NULL, NULL, NULL }; return &des_ede3_cbc;}/* * */static intaes_init(EVP_CIPHER_CTX *ctx, const unsigned char * key, const unsigned char * iv, int encp){ AES_KEY *k = ctx->cipher_data; if (ctx->encrypt) AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k); else AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k); return 1;}static intaes_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size){ AES_KEY *k = ctx->cipher_data; AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt); return 1;}static intaes_cleanup(EVP_CIPHER_CTX *ctx){ memset(ctx->cipher_data, 0, sizeof(AES_KEY)); return 1;}/** * The AES-128 cipher type * * @return the AES-128 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_aes_128_cbc(void){ static const EVP_CIPHER aes_128_cbc = { 0, 16, 16, 16, EVP_CIPH_CBC_MODE, aes_init, aes_do_cipher, aes_cleanup, sizeof(AES_KEY), NULL, NULL, NULL, NULL }; return &aes_128_cbc;}/** * The AES-192 cipher type * * @return the AES-192 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_aes_192_cbc(void){ static const EVP_CIPHER aes_192_cbc = { 0, 16, 24, 16, EVP_CIPH_CBC_MODE, aes_init, aes_do_cipher, aes_cleanup, sizeof(AES_KEY), NULL, NULL, NULL, NULL }; return &aes_192_cbc;}/** * The AES-256 cipher type * * @return the AES-256 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_aes_256_cbc(void){ static const EVP_CIPHER aes_256_cbc = { 0, 16, 32, 16, EVP_CIPH_CBC_MODE, aes_init, aes_do_cipher, aes_cleanup, sizeof(AES_KEY), NULL, NULL, NULL, NULL }; return &aes_256_cbc;}static intcamellia_init(EVP_CIPHER_CTX *ctx, const unsigned char * key, const unsigned char * iv, int encp){ CAMELLIA_KEY *k = ctx->cipher_data; k->bits = ctx->cipher->key_len * 8; CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k); return 1;}static intcamellia_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int size){ CAMELLIA_KEY *k = ctx->cipher_data; CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt); return 1;}static intcamellia_cleanup(EVP_CIPHER_CTX *ctx){ memset(ctx->cipher_data, 0, sizeof(CAMELLIA_KEY)); return 1;}/** * The Camellia-128 cipher type * * @return the Camellia-128 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_camellia_128_cbc(void){ static const EVP_CIPHER cipher = { 0, 16, 16, 16, EVP_CIPH_CBC_MODE, camellia_init, camellia_do_cipher, camellia_cleanup, sizeof(CAMELLIA_KEY), NULL, NULL, NULL, NULL }; return &cipher;}/** * The Camellia-198 cipher type * * @return the Camellia-198 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_camellia_192_cbc(void){ static const EVP_CIPHER cipher = { 0, 16, 24, 16, EVP_CIPH_CBC_MODE, camellia_init, camellia_do_cipher, camellia_cleanup, sizeof(CAMELLIA_KEY), NULL, NULL, NULL, NULL }; return &cipher;}/** * The Camellia-256 cipher type * * @return the Camellia-256 EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_camellia_256_cbc(void){ static const EVP_CIPHER cipher = { 0, 16, 32, 16, EVP_CIPH_CBC_MODE, camellia_init, camellia_do_cipher, camellia_cleanup, sizeof(CAMELLIA_KEY), NULL, NULL, NULL, NULL }; return &cipher;}/* * */static const struct cipher_name { const char *name; const EVP_CIPHER *(*func)(void);} cipher_name[] = { { "des-ede3-cbc", EVP_des_ede3_cbc }, { "aes-128-cbc", EVP_aes_128_cbc }, { "aes-192-cbc", EVP_aes_192_cbc }, { "aes-256-cbc", EVP_aes_256_cbc }, { "camellia-128-cbc", EVP_camellia_128_cbc }, { "camellia-192-cbc", EVP_camellia_192_cbc }, { "camellia-256-cbc", EVP_camellia_256_cbc }};/** * Get the cipher type using their name. * * @param name the name of the cipher. * * @return the selected EVP_CIPHER pointer or NULL if not found. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_get_cipherbyname(const char *name){ int i; for (i = 0; i < sizeof(cipher_name)/sizeof(cipher_name[0]); i++) { if (strcasecmp(cipher_name[i].name, name) == 0) return (*cipher_name[i].func)(); } return NULL;}/* * */#ifndef min#define min(a,b) (((a)>(b))?(b):(a))#endif/** * Provides a legancy string to key function, used in PEM files. * * New protocols should use new string to key functions like NIST * SP56-800A or PKCS#5 v2.0 (see PKCS5_PBKDF2_HMAC_SHA1()). * * @param type type of cipher to use * @param md message digest to use * @param salt salt salt string, should be an binary 8 byte buffer. * @param data the password/input key string. * @param datalen length of data parameter. * @param count iteration counter. * @param keydata output keydata, needs to of the size EVP_CIPHER_key_length(). * @param ivdata output ivdata, needs to of the size EVP_CIPHER_block_size(). * * @return the size of derived key. * * @ingroup hcrypto_evp */intEVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, const void *salt, const void *data, size_t datalen, unsigned int count, void *keydata, void *ivdata){ int ivlen, keylen, first = 0; unsigned int mds = 0, i; unsigned char *key = keydata; unsigned char *iv = ivdata; unsigned char *buf; EVP_MD_CTX c; keylen = EVP_CIPHER_key_length(type); ivlen = EVP_CIPHER_iv_length(type); if (data == NULL) return keylen; buf = malloc(EVP_MD_size(md)); if (buf == NULL) return -1; EVP_MD_CTX_init(&c); first = 1; while (1) { EVP_DigestInit_ex(&c, md, NULL); if (!first) EVP_DigestUpdate(&c, buf, mds); first = 0; EVP_DigestUpdate(&c,data,datalen);#define PKCS5_SALT_LEN 8 if (salt) EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN); EVP_DigestFinal_ex(&c, buf, &mds); assert(mds == EVP_MD_size(md)); for (i = 1; i < count; i++) { EVP_DigestInit_ex(&c, md, NULL); EVP_DigestUpdate(&c, buf, mds); EVP_DigestFinal_ex(&c, buf, &mds); assert(mds == EVP_MD_size(md)); } i = 0; if (keylen) { size_t sz = min(keylen, mds); if (key) { memcpy(key, buf, sz); key += sz; } keylen -= sz; i += sz; } if (ivlen && mds > i) { size_t sz = min(ivlen, (mds - i)); if (iv) { memcpy(iv, &buf[i], sz); iv += sz; } ivlen -= sz; } if (keylen == 0 && ivlen == 0) break; } EVP_MD_CTX_cleanup(&c); free(buf); return EVP_CIPHER_key_length(type);}/** * Add all algorithms to the crypto core. * * @ingroup hcrypto_core */voidOpenSSL_add_all_algorithms(void){ return;}/** * Add all algorithms to the crypto core using configuration file. * * @ingroup hcrypto_core */voidOpenSSL_add_all_algorithms_conf(void){ return;}/** * Add all algorithms to the crypto core, but don't use the * configuration file. * * @ingroup hcrypto_core */voidOpenSSL_add_all_algorithms_noconf(void){ return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -