/*
* Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include "../e_os.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <assert.h>
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/objects.h>
#include <crypto/cryptodev.h>
/* #define ENGINE_DEVCRYPTO_DEBUG */
#if CRYPTO_ALGORITHM_MIN < CRYPTO_ALGORITHM_MAX
# define CHECK_BSD_STYLE_MACROS
#endif
#define engine_devcrypto_id "devcrypto"
/*
* ONE global file descriptor for all sessions. This allows operations
* such as digest session data copying (see digest_copy()), but is also
* saner... why re-open /dev/crypto for every session?
*/
static int cfd = -1;
#define DEVCRYPTO_REQUIRE_ACCELERATED 0 /* require confirmation of acceleration */
#define DEVCRYPTO_USE_SOFTWARE 1 /* allow software drivers */
#define DEVCRYPTO_REJECT_SOFTWARE 2 /* only disallow confirmed software drivers */
#define DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS DEVCRYPTO_REJECT_SOFTWARE
static int use_softdrivers = DEVCRYPTO_DEFAULT_USE_SOFTDRIVERS;
/*
* cipher/digest status & acceleration definitions
* Make sure the defaults are set to 0
*/
struct driver_info_st {
enum devcrypto_status_t {
DEVCRYPTO_STATUS_FAILURE = -3, /* unusable for other reason */
DEVCRYPTO_STATUS_NO_CIOCCPHASH = -2, /* hash state copy not supported */
DEVCRYPTO_STATUS_NO_CIOCGSESSION = -1, /* session open failed */
DEVCRYPTO_STATUS_UNKNOWN = 0, /* not tested yet */
DEVCRYPTO_STATUS_USABLE = 1 /* algo can be used */
} status;
enum devcrypto_accelerated_t {
DEVCRYPTO_NOT_ACCELERATED = -1, /* software implemented */
DEVCRYPTO_ACCELERATION_UNKNOWN = 0, /* acceleration support unknown */
DEVCRYPTO_ACCELERATED = 1 /* hardware accelerated */
} accelerated;
char *driver_name;
};
#ifdef OPENSSL_NO_DYNAMIC_ENGINE
void engine_load_devcrypto_int(void);
#endif
static int clean_devcrypto_session(struct session_op *sess) {
if (ioctl(cfd, CIOCFSESSION, &sess->ses) < 0) {
ERR_raise_data(ERR_LIB_SYS, errno, "calling ioctl()");
return 0;
}
memset(sess, 0, sizeof(struct session_op));
return 1;
}
/******************************************************************************
*
* Ciphers
*
* Because they all do the same basic operation, we have only one set of
* method functions for them all to share, and a mapping table between
* NIDs and cryptodev IDs, with all the necessary size data.
*
*****/
struct cipher_ctx {