diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-02-20 18:56:10 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2012-02-20 18:56:10 +0100 |
commit | 48f8c8da864c8a8acecbe6e6ae7f7b52d1bd4b0d (patch) | |
tree | ab8279a9fd455cc61f24c8813b160b39a1735357 | |
parent | 30a482e8c302312459337cd04e730497980c3a1c (diff) | |
download | gnutls-48f8c8da864c8a8acecbe6e6ae7f7b52d1bd4b0d.tar.gz |
fixes in cryptodev support. Added support for digest algorithms.
-rw-r--r-- | lib/accelerated/cryptodev.c | 125 |
1 files changed, 116 insertions, 9 deletions
diff --git a/lib/accelerated/cryptodev.c b/lib/accelerated/cryptodev.c index 84471c5f23..1a899562c2 100644 --- a/lib/accelerated/cryptodev.c +++ b/lib/accelerated/cryptodev.c @@ -42,14 +42,13 @@ static int cryptodev_fd = -1; -static int register_mac (int cfd); +static int register_mac_digest (int cfd); struct cryptodev_ctx { struct session_op sess; struct crypt_op cryp; uint8_t iv[EALG_MAX_BLOCK_LEN]; - uint8_t key[CRYPTO_CIPHER_MAX_KEY_LEN]; int cfd; }; @@ -80,7 +79,6 @@ cryptodev_cipher_init (gnutls_cipher_algorithm_t algorithm, void **_ctx, int enc ctx->cfd = cryptodev_fd; ctx->sess.cipher = cipher; - ctx->sess.key = ctx->key; ctx->cryp.iv = ctx->iv; return 0; @@ -92,7 +90,7 @@ cryptodev_cipher_setkey (void *_ctx, const void *key, size_t keysize) struct cryptodev_ctx *ctx = _ctx; ctx->sess.keylen = keysize; - memcpy (ctx->key, key, keysize); + ctx->sess.key = (void*)key; if (ioctl (ctx->cfd, CIOCGSESSION, &ctx->sess)) { @@ -251,7 +249,7 @@ _gnutls_cryptodev_init (void) if (ret >= 0) { - ret = register_mac (cryptodev_fd); + ret = register_mac_digest (cryptodev_fd); if (ret < 0) gnutls_assert (); } @@ -303,7 +301,6 @@ cryptodev_mac_init (gnutls_mac_algorithm_t algorithm, void **_ctx) ctx->cfd = cryptodev_fd; ctx->sess.mac = mac; - ctx->sess.mackey = ctx->key; return 0; } @@ -314,7 +311,7 @@ cryptodev_mac_setkey (void *_ctx, const void *key, size_t keysize) struct cryptodev_ctx *ctx = _ctx; ctx->sess.mackeylen = keysize; - memcpy (ctx->key, key, keysize); + ctx->sess.mackey = (void*)key; if (ioctl (ctx->cfd, CIOCGSESSION, &ctx->sess)) { @@ -370,6 +367,9 @@ int mac = gnutls_mac_map[algo]; struct session_op sess; struct crypt_op cryp; + memset(&sess, 0, sizeof(sess)); + memset(&cryp, 0, sizeof(cryp)); + sess.mac = mac; sess.mackey = (void*)key; sess.mackeylen = key_size; @@ -391,6 +391,7 @@ struct crypt_op cryp; gnutls_assert (); return GNUTLS_E_CRYPTODEV_IOCTL_ERROR; } + ioctl (cryptodev_fd, CIOCFSESSION, &sess); return 0; } @@ -406,8 +407,88 @@ static const gnutls_crypto_mac_st mac_struct = { .fast = cryptodev_mac_fast }; +/* Digest algorithms */ + +static const int gnutls_digest_map[] = { + [GNUTLS_DIG_MD5] = CRYPTO_MD5, + [GNUTLS_DIG_SHA1] = CRYPTO_SHA1, + [GNUTLS_DIG_SHA256] = CRYPTO_SHA2_256, + [GNUTLS_DIG_SHA384] = CRYPTO_SHA2_384, + [GNUTLS_DIG_SHA512] = CRYPTO_SHA2_512, +}; + +static int +cryptodev_digest_init (gnutls_digest_algorithm_t algorithm, void **_ctx) +{ + struct cryptodev_ctx *ctx; + int dig = gnutls_digest_map[algorithm]; + + *_ctx = gnutls_calloc (1, sizeof (struct cryptodev_ctx)); + if (*_ctx == NULL) + { + gnutls_assert (); + return GNUTLS_E_MEMORY_ERROR; + } + + ctx = *_ctx; + + ctx->cfd = cryptodev_fd; + + ctx->sess.mac = dig; + + return 0; +} + +#define cryptodev_digest_hash cryptodev_mac_hash +#define cryptodev_digest_output cryptodev_mac_output + +static int +cryptodev_digest_fast (gnutls_digest_algorithm_t algo, + const void *text, size_t text_size, + void *digest) +{ +int dig = gnutls_digest_map[algo]; +struct session_op sess; +struct crypt_op cryp; + + memset(&sess, 0, sizeof(sess)); + memset(&cryp, 0, sizeof(cryp)); + sess.mac = dig; + + if (ioctl (cryptodev_fd, CIOCGSESSION, &sess)) + { + gnutls_assert (); + return GNUTLS_E_CRYPTODEV_IOCTL_ERROR; + } + cryp.ses = sess.ses; + cryp.len = text_size; + cryp.src = (void *) text; + cryp.dst = NULL; + cryp.mac = digest; + cryp.op = COP_ENCRYPT; + + if (ioctl (cryptodev_fd, CIOCCRYPT, &cryp)) + { + gnutls_assert (); + return GNUTLS_E_CRYPTODEV_IOCTL_ERROR; + } + ioctl (cryptodev_fd, CIOCFSESSION, &sess); + + return 0; +} + +#define cryptodev_digest_deinit cryptodev_deinit + +static const gnutls_crypto_digest_st digest_struct = { + .init = cryptodev_digest_init, + .hash = cryptodev_digest_hash, + .output = cryptodev_digest_output, + .deinit = cryptodev_digest_deinit, + .fast = cryptodev_digest_fast +}; + static int -register_mac (int cfd) +register_mac_digest (int cfd) { struct session_op sess; uint8_t fake_key[CRYPTO_CIPHER_MAX_KEY_LEN]; @@ -442,12 +523,38 @@ register_mac (int cfd) } + memset (&sess, 0, sizeof (sess)); + for (i = 0; i < sizeof (gnutls_digest_map) / sizeof (gnutls_digest_map[0]); i++) + { + if (gnutls_digest_map[i] == 0) + continue; + + sess.mac = gnutls_digest_map[i]; + + if (ioctl (cfd, CIOCGSESSION, &sess)) + { + continue; + } + + ioctl (cfd, CIOCFSESSION, &sess); + + _gnutls_debug_log ("/dev/crypto: registering: %s\n", + gnutls_mac_get_name (i)); + ret = gnutls_crypto_single_digest_register (i, 90, &digest_struct); + if (ret < 0) + { + gnutls_assert (); + return ret; + } + + } + return 0; } #else static int -register_mac (int cfd) +register_mac_digest (int cfd) { return 0; } |