Signed-off-by: Phil Sutter <phil.sut...@viprinet.com> --- tests/openssl_wrapper.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++ tests/openssl_wrapper.h | 6 + 2 files changed, 273 insertions(+), 0 deletions(-) create mode 100644 tests/openssl_wrapper.c create mode 100644 tests/openssl_wrapper.h
diff --git a/tests/openssl_wrapper.c b/tests/openssl_wrapper.c new file mode 100644 index 0000000..038c58f --- /dev/null +++ b/tests/openssl_wrapper.c @@ -0,0 +1,267 @@ +#include <crypto/cryptodev.h> +#include <stdio.h> +#include <string.h> +#include <openssl/aes.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> + +//#define DEBUG + +#ifdef DEBUG +# define dbgp(...) { \ + fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ +} +#else +# define dbgp(...) /* nothing */ +#endif + +enum ctx_type { + ctx_type_none = 0, + ctx_type_hmac, + ctx_type_md, +}; + +union openssl_ctx { + HMAC_CTX hmac; + EVP_MD_CTX md; +}; + +struct ctx_mapping { + __u32 ses; + enum ctx_type type; + union openssl_ctx ctx; +}; + +static struct ctx_mapping ctx_map[512]; + +static struct ctx_mapping *find_mapping(__u32 ses) +{ + int i; + + for (i = 0; i < 512; i++) { + if (ctx_map[i].ses == ses) + return &ctx_map[i]; + } + return NULL; +} + +static struct ctx_mapping *new_mapping(void) +{ + return find_mapping(0); +} + +static void remove_mapping(__u32 ses) +{ + struct ctx_mapping *mapping; + + if (!(mapping = find_mapping(ses))) { + printf("%s: failed to find mapping for session %d\n", __func__, ses); + return; + } + switch (mapping->type) { + case ctx_type_none: + break; + case ctx_type_hmac: + dbgp("%s: calling HMAC_CTX_cleanup\n", __func__); + HMAC_CTX_cleanup(&mapping->ctx.hmac); + break; + case ctx_type_md: + dbgp("%s: calling EVP_MD_CTX_cleanup\n", __func__); + EVP_MD_CTX_cleanup(&mapping->ctx.md); + break; + } + memset(mapping, 0, sizeof(*mapping)); +} + +static union openssl_ctx *__ses_to_ctx(__u32 ses) +{ + struct ctx_mapping *mapping; + + if (!(mapping = find_mapping(ses))) + return NULL; + return &mapping->ctx; +} + +static HMAC_CTX *ses_to_hmac(__u32 ses) { return (HMAC_CTX *)__ses_to_ctx(ses); } +static EVP_MD_CTX *ses_to_md(__u32 ses) { return (EVP_MD_CTX *)__ses_to_ctx(ses); } + +static const EVP_MD *sess_to_evp_md(struct session_op *sess) +{ + switch (sess->mac) { +#ifndef OPENSSL_NO_MD5 + case CRYPTO_MD5_HMAC: return EVP_md5(); +#endif +#ifndef OPENSSL_NO_SHA + case CRYPTO_SHA1_HMAC: + case CRYPTO_SHA1: + return EVP_sha1(); +#endif +#ifndef OPENSSL_NO_RIPEMD + case CRYPTO_RIPEMD160_HMAC: return EVP_ripemd160(); +#endif +#ifndef OPENSSL_NO_SHA256 + case CRYPTO_SHA2_256_HMAC: return EVP_sha256(); +#endif +#ifndef OPENSSL_NO_SHA512 + case CRYPTO_SHA2_384_HMAC: return EVP_sha384(); + case CRYPTO_SHA2_512_HMAC: return EVP_sha512(); +#endif + default: + printf("%s: failed to get an EVP, things will be broken!\n", __func__); + return NULL; + } +} + +static int openssl_hmac(struct session_op *sess, struct crypt_op *cop) +{ + HMAC_CTX *ctx = ses_to_hmac(sess->ses); + + if (!ctx) { + struct ctx_mapping *mapping = new_mapping(); + if (!mapping) { + printf("%s: failed to get new mapping\n", __func__); + return 1; + } + + mapping->ses = sess->ses; + mapping->type = ctx_type_hmac; + ctx = &mapping->ctx.hmac; + + dbgp("calling HMAC_CTX_init"); + HMAC_CTX_init(ctx); + dbgp("calling HMAC_Init_ex"); + if (!HMAC_Init_ex(ctx, sess->mackey, sess->mackeylen, + sess_to_evp_md(sess), NULL)) { + printf("%s: HMAC_Init_ex failed\n", __func__); + return 1; + } + } + + if (cop->len) { + dbgp("calling HMAC_Update"); + if (!HMAC_Update(ctx, cop->src, cop->len)) { + printf("%s: HMAC_Update failed\n", __func__); + return 1; + } + } + if (cop->flags & COP_FLAG_FINAL || + (cop->len && !(cop->flags & COP_FLAG_UPDATE))) { + dbgp("calling HMAC_Final"); + if (!HMAC_Final(ctx, cop->mac, 0)) { + printf("%s: HMAC_Final failed\n", __func__); + remove_mapping(sess->ses); + return 1; + } + remove_mapping(sess->ses); + } + return 0; +} + +static int openssl_md(struct session_op *sess, struct crypt_op *cop) +{ + EVP_MD_CTX *ctx = ses_to_md(sess->ses); + + if (!ctx) { + struct ctx_mapping *mapping = new_mapping(); + if (!mapping) { + printf("%s: failed to get new mapping\n", __func__); + return 1; + } + + mapping->ses = sess->ses; + mapping->type = ctx_type_md; + ctx = &mapping->ctx.md; + + dbgp("calling EVP_MD_CTX_init"); + EVP_MD_CTX_init(ctx); + dbgp("calling EVP_DigestInit"); + EVP_DigestInit(ctx, sess_to_evp_md(sess)); + } + + if (cop->len) { + dbgp("calling EVP_DigestUpdate"); + EVP_DigestUpdate(ctx, cop->src, cop->len); + } + if (cop->flags & COP_FLAG_FINAL || + (cop->len && !(cop->flags & COP_FLAG_UPDATE))) { + dbgp("calling EVP_DigestFinal"); + EVP_DigestFinal(ctx, cop->mac, 0); + remove_mapping(sess->ses); + } + + return 0; +} + +static int openssl_aes(struct session_op *sess, struct crypt_op *cop) +{ + AES_KEY key; + int i, enc; + unsigned char ivec[AES_BLOCK_SIZE]; + + if (cop->len % AES_BLOCK_SIZE) { + printf("%s: illegal length passed, " + "not a multiple of AES_BLOCK_SIZE\n", __func__); + return 1; + } + + switch (cop->op) { + case COP_ENCRYPT: + AES_set_encrypt_key(sess->key, sess->keylen * 8, &key); + enc = 1; + break; + case COP_DECRYPT: + AES_set_decrypt_key(sess->key, sess->keylen * 8, &key); + enc = 0; + break; + default: + printf("%s: unknown cop->op received!\n", __func__); + return 1; + } + + switch (sess->cipher) { + case CRYPTO_AES_CBC: + memcpy(ivec, cop->iv, AES_BLOCK_SIZE); + AES_cbc_encrypt(cop->src, cop->dst, cop->len, &key, ivec, enc); + if (cop->flags & COP_FLAG_WRITE_IV) + memcpy(cop->iv, ivec, AES_BLOCK_SIZE); + break; +#if 0 + /* XXX: TODO: implement this stuff */ + case CRYPTO_AES_CTR: + AES_ctr128_encrypt(cop->src, cop->dst, &key, cop->iv, + case CRYPTO_AES_XTS: +#endif + case CRYPTO_AES_ECB: + for (i = 0; i < cop->len; i += AES_BLOCK_SIZE) + AES_ecb_encrypt(cop->src + i, cop->dst + i, &key, enc); + break; + } + return 0; +} + +int openssl_cioccrypt(struct session_op *sess, struct crypt_op *cop) +{ + if (sess->mac && sess->mackey && sess->mackeylen) + openssl_hmac(sess, cop); + else if (sess->mac) + openssl_md(sess, cop); + + switch (sess->cipher) { + case CRYPTO_AES_CBC: + case CRYPTO_AES_CTR: + case CRYPTO_AES_XTS: + case CRYPTO_AES_ECB: + openssl_aes(sess, cop); + break; + case 0: + /* no encryption wanted, everythings fine */ + break; + default: + printf("%s: unknown cipher passed!\n", __func__); + break; + } + + return 0; +} diff --git a/tests/openssl_wrapper.h b/tests/openssl_wrapper.h new file mode 100644 index 0000000..5f1f516 --- /dev/null +++ b/tests/openssl_wrapper.h @@ -0,0 +1,6 @@ +#ifndef __OPENSSL_WRAPPER_H +#define __OPENSSL_WRAPPER_H + +int openssl_cioccrypt(struct session_op *, struct crypt_op *); + +#endif /* __OPENSSL_WRAPPER_H */ -- 1.7.3.4 _______________________________________________ Cryptodev-linux-devel mailing list Cryptodev-linux-devel@gna.org https://mail.gna.org/listinfo/cryptodev-linux-devel