|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2009-2010, 2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: Nikos Mavrogiannopoulos
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This file is part of GnuTLS.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit Service |
4684c1 |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
4684c1 |
* the License, or (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This library is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* Lesser General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include <gnutls/crypto.h>
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
#include <accelerated/cryptodev.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef ENABLE_CRYPTODEV
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <assert.h>
|
|
Packit Service |
4684c1 |
#include <fcntl.h>
|
|
Packit Service |
4684c1 |
#include <sys/ioctl.h>
|
|
Packit Service |
4684c1 |
#include <crypto/cryptodev.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifndef CRYPTO_CIPHER_MAX_KEY_LEN
|
|
Packit Service |
4684c1 |
#define CRYPTO_CIPHER_MAX_KEY_LEN 64
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifndef EALG_MAX_BLOCK_LEN
|
|
Packit Service |
4684c1 |
#define EALG_MAX_BLOCK_LEN 16
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_cryptodev_fd = -1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int register_mac_digest(int cfd);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx {
|
|
Packit Service |
4684c1 |
struct session_op sess;
|
|
Packit Service |
4684c1 |
struct crypt_op cryp;
|
|
Packit Service |
4684c1 |
uint8_t iv[EALG_MAX_BLOCK_LEN];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int cfd;
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const int gnutls_cipher_map[] = {
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_AES_128_CBC] = CRYPTO_AES_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_AES_192_CBC] = CRYPTO_AES_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_AES_256_CBC] = CRYPTO_AES_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_3DES_CBC] = CRYPTO_3DES_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_CAMELLIA_128_CBC] = CRYPTO_CAMELLIA_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_CAMELLIA_192_CBC] = CRYPTO_CAMELLIA_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_CAMELLIA_256_CBC] = CRYPTO_CAMELLIA_CBC,
|
|
Packit Service |
4684c1 |
[GNUTLS_CIPHER_DES_CBC] = CRYPTO_DES_CBC,
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_cipher_init(gnutls_cipher_algorithm_t algorithm, void **_ctx,
|
|
Packit Service |
4684c1 |
int enc)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx;
|
|
Packit Service |
4684c1 |
int cipher = gnutls_cipher_map[algorithm];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
*_ctx = gnutls_calloc(1, sizeof(struct cryptodev_ctx));
|
|
Packit Service |
4684c1 |
if (*_ctx == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx = *_ctx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx->cfd = _gnutls_cryptodev_fd;
|
|
Packit Service |
4684c1 |
ctx->sess.cipher = cipher;
|
|
Packit Service |
4684c1 |
ctx->cryp.iv = ctx->iv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_cipher_setkey(void *_ctx, const void *key, size_t keysize)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx = _ctx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
CHECK_AES_KEYSIZE(keysize);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx->sess.keylen = keysize;
|
|
Packit Service |
4684c1 |
ctx->sess.key = (void *) key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
ctx->cryp.ses = ctx->sess.ses;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int cryptodev_setiv(void *_ctx, const void *iv, size_t iv_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx = _ctx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (iv_size > EALG_MAX_BLOCK_LEN)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(ctx->iv, iv, iv_size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_encrypt(void *_ctx, const void *src, size_t src_size,
|
|
Packit Service |
4684c1 |
void *dst, size_t dst_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx = _ctx;
|
|
Packit Service |
4684c1 |
ctx->cryp.len = src_size;
|
|
Packit Service |
4684c1 |
ctx->cryp.src = (void *) src;
|
|
Packit Service |
4684c1 |
ctx->cryp.dst = dst;
|
|
Packit Service |
4684c1 |
ctx->cryp.op = COP_ENCRYPT;
|
|
Packit Service |
4684c1 |
ctx->cryp.flags = COP_FLAG_WRITE_IV;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(ctx->cfd, CIOCCRYPT, &ctx->cryp)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_decrypt(void *_ctx, const void *src, size_t src_size,
|
|
Packit Service |
4684c1 |
void *dst, size_t dst_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx = _ctx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx->cryp.len = src_size;
|
|
Packit Service |
4684c1 |
ctx->cryp.src = (void *) src;
|
|
Packit Service |
4684c1 |
ctx->cryp.dst = dst;
|
|
Packit Service |
4684c1 |
ctx->cryp.op = COP_DECRYPT;
|
|
Packit Service |
4684c1 |
ctx->cryp.flags = COP_FLAG_WRITE_IV;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(ctx->cfd, CIOCCRYPT, &ctx->cryp)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void cryptodev_deinit(void *_ctx)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx *ctx = _ctx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses);
|
|
Packit Service |
4684c1 |
gnutls_free(ctx);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const gnutls_crypto_cipher_st cipher_struct = {
|
|
Packit Service |
4684c1 |
.init = cryptodev_cipher_init,
|
|
Packit Service |
4684c1 |
.setkey = cryptodev_cipher_setkey,
|
|
Packit Service |
4684c1 |
.setiv = cryptodev_setiv,
|
|
Packit Service |
4684c1 |
.encrypt = cryptodev_encrypt,
|
|
Packit Service |
4684c1 |
.decrypt = cryptodev_decrypt,
|
|
Packit Service |
4684c1 |
.deinit = cryptodev_deinit,
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int register_crypto(int cfd)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct session_op sess;
|
|
Packit Service |
4684c1 |
uint8_t fake_key[CRYPTO_CIPHER_MAX_KEY_LEN];
|
|
Packit Service |
4684c1 |
unsigned int i;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
#ifdef CIOCGSESSINFO
|
|
Packit Service |
4684c1 |
struct session_info_op siop;
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&sess, 0, sizeof(sess));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i = 0;
|
|
Packit Service |
4684c1 |
i < sizeof(gnutls_cipher_map) / sizeof(gnutls_cipher_map[0]);
|
|
Packit Service |
4684c1 |
i++) {
|
|
Packit Service |
4684c1 |
if (gnutls_cipher_map[i] == 0)
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* test if a cipher is supported and if yes register it */
|
|
Packit Service |
4684c1 |
sess.cipher = gnutls_cipher_map[i];
|
|
Packit Service |
4684c1 |
sess.keylen = gnutls_cipher_get_key_size(i);
|
|
Packit Service |
4684c1 |
sess.key = fake_key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSION, &sess)) {
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#ifdef CIOCGSESSINFO
|
|
Packit Service |
4684c1 |
memset(&siop, 0, sizeof(siop));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
siop.ses = sess.ses; /* do not register ciphers that are not hw accelerated */
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSINFO, &siop) == 0) {
|
|
Packit Service |
4684c1 |
if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) {
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("/dev/crypto: registering: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_cipher_get_name(i));
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_crypto_single_cipher_register(i, 90,
|
|
Packit Service |
4684c1 |
&cipher_struct, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#ifdef CIOCAUTHCRYPT
|
|
Packit Service |
4684c1 |
return _cryptodev_register_gcm_crypto(cfd);
|
|
Packit Service |
4684c1 |
#else
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_cryptodev_init(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Open the crypto device */
|
|
Packit Service |
4684c1 |
_gnutls_cryptodev_fd = open("/dev/crypto", O_RDWR, 0);
|
|
Packit Service |
4684c1 |
if (_gnutls_cryptodev_fd < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_DEVICE_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#ifndef CRIOGET_NOT_NEEDED
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int cfd = -1;
|
|
Packit Service |
4684c1 |
/* Clone file descriptor */
|
|
Packit Service |
4684c1 |
if (ioctl(_gnutls_cryptodev_fd, CRIOGET, &cfd)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Set close-on-exec (not really needed here) */
|
|
Packit Service |
4684c1 |
if (fcntl(cfd, F_SETFD, 1) == -1) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_CRYPTODEV_IOCTL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
close(_gnutls_cryptodev_fd);
|
|
Packit Service |
4684c1 |
_gnutls_cryptodev_fd = cfd;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = register_crypto(_gnutls_cryptodev_fd);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret >= 0) {
|
|
Packit Service |
4684c1 |
ret = register_mac_digest(_gnutls_cryptodev_fd);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
close(_gnutls_cryptodev_fd);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void _gnutls_cryptodev_deinit(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (_gnutls_cryptodev_fd != -1)
|
|
Packit Service |
4684c1 |
close(_gnutls_cryptodev_fd);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* MAC and digest stuff */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* if we are using linux /dev/crypto
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
#if defined(COP_FLAG_UPDATE) && defined(COP_FLAG_RESET)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const int gnutls_mac_map[] = {
|
|
Packit Service |
4684c1 |
[GNUTLS_MAC_MD5] = CRYPTO_MD5_HMAC,
|
|
Packit Service |
4684c1 |
[GNUTLS_MAC_SHA1] = CRYPTO_SHA1_HMAC,
|
|
Packit Service |
4684c1 |
[GNUTLS_MAC_SHA256] = CRYPTO_SHA2_256_HMAC,
|
|
Packit Service |
4684c1 |
[GNUTLS_MAC_SHA384] = CRYPTO_SHA2_384_HMAC,
|
|
Packit Service |
4684c1 |
[GNUTLS_MAC_SHA512] = CRYPTO_SHA2_512_HMAC,
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_mac_fast(gnutls_mac_algorithm_t algo,
|
|
Packit Service |
4684c1 |
const void *nonce, size_t nonce_size,
|
|
Packit Service |
4684c1 |
const void *key, size_t key_size, const void *text,
|
|
Packit Service |
4684c1 |
size_t text_size, void *digest)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx ctx;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert(nonce_size == 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&ctx, 0, sizeof(ctx));
|
|
Packit Service |
4684c1 |
ctx.cfd = _gnutls_cryptodev_fd;
|
|
Packit Service |
4684c1 |
ctx.sess.mac = gnutls_mac_map[algo];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx.sess.mackeylen = key_size;
|
|
Packit Service |
4684c1 |
ctx.sess.mackey = (void *) key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(ctx.cfd, CIOCGSESSION, &ctx.sess))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_CRYPTODEV_IOCTL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx.cryp.ses = ctx.sess.ses;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx.cryp.len = text_size;
|
|
Packit Service |
4684c1 |
ctx.cryp.src = (void *) text;
|
|
Packit Service |
4684c1 |
ctx.cryp.dst = NULL;
|
|
Packit Service |
4684c1 |
ctx.cryp.op = COP_ENCRYPT;
|
|
Packit Service |
4684c1 |
ctx.cryp.mac = digest;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = ioctl(ctx.cfd, CIOCCRYPT, &ctx.cryp);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(_gnutls_cryptodev_fd, CIOCFSESSION, &ctx.sess.ses);
|
|
Packit Service |
4684c1 |
if (ret != 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_CRYPTODEV_IOCTL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define cryptodev_mac_deinit cryptodev_deinit
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const gnutls_crypto_mac_st mac_struct = {
|
|
Packit Service |
4684c1 |
.init = NULL,
|
|
Packit Service |
4684c1 |
.setkey = NULL,
|
|
Packit Service |
4684c1 |
.setnonce = NULL,
|
|
Packit Service |
4684c1 |
.hash = NULL,
|
|
Packit Service |
4684c1 |
.output = NULL,
|
|
Packit Service |
4684c1 |
.deinit = NULL,
|
|
Packit Service |
4684c1 |
.fast = cryptodev_mac_fast
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Digest algorithms */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const int gnutls_digest_map[] = {
|
|
Packit Service |
4684c1 |
[GNUTLS_DIG_MD5] = CRYPTO_MD5,
|
|
Packit Service |
4684c1 |
[GNUTLS_DIG_SHA1] = CRYPTO_SHA1,
|
|
Packit Service |
4684c1 |
[GNUTLS_DIG_SHA256] = CRYPTO_SHA2_256,
|
|
Packit Service |
4684c1 |
[GNUTLS_DIG_SHA384] = CRYPTO_SHA2_384,
|
|
Packit Service |
4684c1 |
[GNUTLS_DIG_SHA512] = CRYPTO_SHA2_512,
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
cryptodev_digest_fast(gnutls_digest_algorithm_t algo,
|
|
Packit Service |
4684c1 |
const void *text, size_t text_size, void *digest)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct cryptodev_ctx ctx;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&ctx, 0, sizeof(ctx));
|
|
Packit Service |
4684c1 |
ctx.cfd = _gnutls_cryptodev_fd;
|
|
Packit Service |
4684c1 |
ctx.sess.mac = gnutls_digest_map[algo];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(ctx.cfd, CIOCGSESSION, &ctx.sess))
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_CRYPTODEV_IOCTL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx.cryp.ses = ctx.sess.ses;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ctx.cryp.len = text_size;
|
|
Packit Service |
4684c1 |
ctx.cryp.src = (void *) text;
|
|
Packit Service |
4684c1 |
ctx.cryp.dst = NULL;
|
|
Packit Service |
4684c1 |
ctx.cryp.op = COP_ENCRYPT;
|
|
Packit Service |
4684c1 |
ctx.cryp.mac = digest;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = ioctl(ctx.cfd, CIOCCRYPT, &ctx.cryp);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(_gnutls_cryptodev_fd, CIOCFSESSION, &ctx.sess.ses);
|
|
Packit Service |
4684c1 |
if (ret != 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_CRYPTODEV_IOCTL_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const gnutls_crypto_digest_st digest_struct = {
|
|
Packit Service |
4684c1 |
.init = NULL,
|
|
Packit Service |
4684c1 |
.hash = NULL,
|
|
Packit Service |
4684c1 |
.output = NULL,
|
|
Packit Service |
4684c1 |
.deinit = NULL,
|
|
Packit Service |
4684c1 |
.fast = cryptodev_digest_fast
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int register_mac_digest(int cfd)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct session_op sess;
|
|
Packit Service |
4684c1 |
uint8_t fake_key[CRYPTO_CIPHER_MAX_KEY_LEN];
|
|
Packit Service |
4684c1 |
unsigned int i;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
#ifdef CIOCGSESSINFO
|
|
Packit Service |
4684c1 |
struct session_info_op siop;
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&sess, 0, sizeof(sess));
|
|
Packit Service |
4684c1 |
for (i = 0; i < sizeof(gnutls_mac_map) / sizeof(gnutls_mac_map[0]);
|
|
Packit Service |
4684c1 |
i++) {
|
|
Packit Service |
4684c1 |
if (gnutls_mac_map[i] == 0)
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
sess.mac = gnutls_mac_map[i];
|
|
Packit Service |
4684c1 |
sess.mackeylen = 8;
|
|
Packit Service |
4684c1 |
sess.mackey = fake_key;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSION, &sess)) {
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#ifdef CIOCGSESSINFO
|
|
Packit Service |
4684c1 |
memset(&siop, 0, sizeof(siop));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
siop.ses = sess.ses; /* do not register ciphers that are not hw accelerated */
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSINFO, &siop) == 0) {
|
|
Packit Service |
4684c1 |
if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) {
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("/dev/crypto: registering: HMAC-%s\n",
|
|
Packit Service |
4684c1 |
gnutls_mac_get_name(i));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_crypto_single_mac_register(i, 90, &mac_struct, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&sess, 0, sizeof(sess));
|
|
Packit Service |
4684c1 |
for (i = 0;
|
|
Packit Service |
4684c1 |
i < sizeof(gnutls_digest_map) / sizeof(gnutls_digest_map[0]);
|
|
Packit Service |
4684c1 |
i++) {
|
|
Packit Service |
4684c1 |
if (gnutls_digest_map[i] == 0)
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
sess.mac = gnutls_digest_map[i];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSION, &sess)) {
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#ifdef CIOCGSESSINFO
|
|
Packit Service |
4684c1 |
memset(&siop, 0, sizeof(siop));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
siop.ses = sess.ses;
|
|
Packit Service |
4684c1 |
if (ioctl(cfd, CIOCGSESSINFO, &siop) == 0) {
|
|
Packit Service |
4684c1 |
if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) {
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ioctl(cfd, CIOCFSESSION, &sess.ses);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("/dev/crypto: registering: %s\n",
|
|
Packit Service |
4684c1 |
gnutls_mac_get_name(i));
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
gnutls_crypto_single_digest_register(i, 90,
|
|
Packit Service |
4684c1 |
&digest_struct, 0);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#else
|
|
Packit Service |
4684c1 |
static int register_mac_digest(int cfd)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#endif /* defined(COP_FLAG_UPDATE) */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#else /* ENABLE_CRYPTODEV */
|
|
Packit Service |
4684c1 |
int _gnutls_cryptodev_init(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void _gnutls_cryptodev_deinit(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif /* ENABLE_CRYPTODEV */
|