280 lines
10 KiB
Diff
280 lines
10 KiB
Diff
From cb186f682679383e8b5806240927903730ce85d9 Mon Sep 17 00:00:00 2001
|
|
From: Michael Weiser <michael.weiser@gmx.de>
|
|
Date: Fri, 5 Aug 2016 17:26:27 +0200
|
|
Subject: [PATCH] Support skcipher in addition to ablkcipher API
|
|
|
|
The ablkcipher API is being phased out[1]. The unified skcipher API
|
|
seems to have made its entry with 4.3.[3, 4] By what can be seen from
|
|
migration patches[1.ff.], it's a drop-in replacement.
|
|
|
|
Also, deallocators such as crypto_free_skcipher() are NULL-safe now[2].
|
|
|
|
Add a new header cipherapi.h to aid migration from ablkcipher to skcipher and
|
|
retain support for old kernels. Make it decide which API to use and provide
|
|
appropriate function calls and type definitions. Since the ablkcipher and
|
|
skcipher APIs are so similar, those are mainly defines for corresponding
|
|
pseudo-functions in namespace cryptodev_ derived directly from their API
|
|
counterparts.
|
|
|
|
Compiles and works (i.e. checks pass) with Debian testing 4.6.4 kernel
|
|
as well as 4.8-rc2+ Linus git tree as of today. (Both require a fix for
|
|
changed page access API[5].)
|
|
|
|
[1] https://www.spinics.net/lists/linux-crypto/msg18133.html
|
|
[2] https://www.spinics.net/lists/linux-crypto/msg18154.html, line 120
|
|
[3] https://www.spinics.net/lists/linux-crypto/msg16373.html
|
|
[4] https://www.spinics.net/lists/linux-crypto/msg16294.html
|
|
[5] https://github.com/cryptodev-linux/cryptodev-linux/pull/14
|
|
---
|
|
cipherapi.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
cryptlib.c | 40 ++++++++++++++++++----------------------
|
|
cryptlib.h | 6 ++++--
|
|
ioctl.c | 4 ++--
|
|
4 files changed, 84 insertions(+), 26 deletions(-)
|
|
create mode 100644 cipherapi.h
|
|
|
|
Upstream-Status: Backport [from master for 4.8 kernels]
|
|
|
|
Index: cryptodev-linux-1.8/cipherapi.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ cryptodev-linux-1.8/cipherapi.h
|
|
@@ -0,0 +1,60 @@
|
|
+#ifndef CIPHERAPI_H
|
|
+# define CIPHERAPI_H
|
|
+
|
|
+#include <linux/version.h>
|
|
+
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
|
|
+# include <linux/crypto.h>
|
|
+
|
|
+typedef struct ablkcipher_alg cryptodev_blkcipher_alg_t;
|
|
+typedef struct crypto_ablkcipher cryptodev_crypto_blkcipher_t;
|
|
+typedef struct ablkcipher_request cryptodev_blkcipher_request_t;
|
|
+
|
|
+# define cryptodev_crypto_alloc_blkcipher crypto_alloc_ablkcipher
|
|
+# define cryptodev_crypto_blkcipher_alg crypto_ablkcipher_alg
|
|
+# define cryptodev_crypto_blkcipher_blocksize crypto_ablkcipher_blocksize
|
|
+# define cryptodev_crypto_blkcipher_ivsize crypto_ablkcipher_ivsize
|
|
+# define cryptodev_crypto_blkcipher_alignmask crypto_ablkcipher_alignmask
|
|
+# define cryptodev_crypto_blkcipher_setkey crypto_ablkcipher_setkey
|
|
+
|
|
+static inline void cryptodev_crypto_free_blkcipher(cryptodev_crypto_blkcipher_t *c) {
|
|
+ if (c)
|
|
+ crypto_free_ablkcipher(c);
|
|
+}
|
|
+
|
|
+# define cryptodev_blkcipher_request_alloc ablkcipher_request_alloc
|
|
+# define cryptodev_blkcipher_request_set_callback ablkcipher_request_set_callback
|
|
+
|
|
+static inline void cryptodev_blkcipher_request_free(cryptodev_blkcipher_request_t *r) {
|
|
+ if (r)
|
|
+ ablkcipher_request_free(r);
|
|
+}
|
|
+
|
|
+# define cryptodev_blkcipher_request_set_crypt ablkcipher_request_set_crypt
|
|
+# define cryptodev_crypto_blkcipher_encrypt crypto_ablkcipher_encrypt
|
|
+# define cryptodev_crypto_blkcipher_decrypt crypto_ablkcipher_decrypt
|
|
+# define cryptodev_crypto_blkcipher_tfm crypto_ablkcipher_tfm
|
|
+#else
|
|
+#include <crypto/skcipher.h>
|
|
+
|
|
+typedef struct skcipher_alg cryptodev_blkcipher_alg_t;
|
|
+typedef struct crypto_skcipher cryptodev_crypto_blkcipher_t;
|
|
+typedef struct skcipher_request cryptodev_blkcipher_request_t;
|
|
+
|
|
+# define cryptodev_crypto_alloc_blkcipher crypto_alloc_skcipher
|
|
+# define cryptodev_crypto_blkcipher_alg crypto_skcipher_alg
|
|
+# define cryptodev_crypto_blkcipher_blocksize crypto_skcipher_blocksize
|
|
+# define cryptodev_crypto_blkcipher_ivsize crypto_skcipher_ivsize
|
|
+# define cryptodev_crypto_blkcipher_alignmask crypto_skcipher_alignmask
|
|
+# define cryptodev_crypto_blkcipher_setkey crypto_skcipher_setkey
|
|
+# define cryptodev_crypto_free_blkcipher crypto_free_skcipher
|
|
+# define cryptodev_blkcipher_request_alloc skcipher_request_alloc
|
|
+# define cryptodev_blkcipher_request_set_callback skcipher_request_set_callback
|
|
+# define cryptodev_blkcipher_request_free skcipher_request_free
|
|
+# define cryptodev_blkcipher_request_set_crypt skcipher_request_set_crypt
|
|
+# define cryptodev_crypto_blkcipher_encrypt crypto_skcipher_encrypt
|
|
+# define cryptodev_crypto_blkcipher_decrypt crypto_skcipher_decrypt
|
|
+# define cryptodev_crypto_blkcipher_tfm crypto_skcipher_tfm
|
|
+#endif
|
|
+
|
|
+#endif
|
|
Index: cryptodev-linux-1.8/cryptlib.c
|
|
===================================================================
|
|
--- cryptodev-linux-1.8.orig/cryptlib.c
|
|
+++ cryptodev-linux-1.8/cryptlib.c
|
|
@@ -23,7 +23,6 @@
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
-#include <linux/crypto.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/ioctl.h>
|
|
@@ -37,6 +36,7 @@
|
|
#include <linux/rtnetlink.h>
|
|
#include <crypto/authenc.h>
|
|
#include "cryptodev_int.h"
|
|
+#include "cipherapi.h"
|
|
|
|
|
|
struct cryptodev_result {
|
|
@@ -133,15 +133,15 @@ int cryptodev_cipher_init(struct cipher_
|
|
int ret;
|
|
|
|
if (aead == 0) {
|
|
- struct ablkcipher_alg *alg;
|
|
+ cryptodev_blkcipher_alg_t *alg;
|
|
|
|
- out->async.s = crypto_alloc_ablkcipher(alg_name, 0, 0);
|
|
+ out->async.s = cryptodev_crypto_alloc_blkcipher(alg_name, 0, 0);
|
|
if (unlikely(IS_ERR(out->async.s))) {
|
|
ddebug(1, "Failed to load cipher %s", alg_name);
|
|
return -EINVAL;
|
|
}
|
|
|
|
- alg = crypto_ablkcipher_alg(out->async.s);
|
|
+ alg = cryptodev_crypto_blkcipher_alg(out->async.s);
|
|
if (alg != NULL) {
|
|
/* Was correct key length supplied? */
|
|
if (alg->max_keysize > 0 &&
|
|
@@ -154,11 +154,11 @@ int cryptodev_cipher_init(struct cipher_
|
|
}
|
|
}
|
|
|
|
- out->blocksize = crypto_ablkcipher_blocksize(out->async.s);
|
|
- out->ivsize = crypto_ablkcipher_ivsize(out->async.s);
|
|
- out->alignmask = crypto_ablkcipher_alignmask(out->async.s);
|
|
+ out->blocksize = cryptodev_crypto_blkcipher_blocksize(out->async.s);
|
|
+ out->ivsize = cryptodev_crypto_blkcipher_ivsize(out->async.s);
|
|
+ out->alignmask = cryptodev_crypto_blkcipher_alignmask(out->async.s);
|
|
|
|
- ret = crypto_ablkcipher_setkey(out->async.s, keyp, keylen);
|
|
+ ret = cryptodev_crypto_blkcipher_setkey(out->async.s, keyp, keylen);
|
|
} else {
|
|
out->async.as = crypto_alloc_aead(alg_name, 0, 0);
|
|
if (unlikely(IS_ERR(out->async.as))) {
|
|
@@ -191,14 +191,14 @@ int cryptodev_cipher_init(struct cipher_
|
|
init_completion(&out->async.result->completion);
|
|
|
|
if (aead == 0) {
|
|
- out->async.request = ablkcipher_request_alloc(out->async.s, GFP_KERNEL);
|
|
+ out->async.request = cryptodev_blkcipher_request_alloc(out->async.s, GFP_KERNEL);
|
|
if (unlikely(!out->async.request)) {
|
|
derr(1, "error allocating async crypto request");
|
|
ret = -ENOMEM;
|
|
goto error;
|
|
}
|
|
|
|
- ablkcipher_request_set_callback(out->async.request,
|
|
+ cryptodev_blkcipher_request_set_callback(out->async.request,
|
|
CRYPTO_TFM_REQ_MAY_BACKLOG,
|
|
cryptodev_complete, out->async.result);
|
|
} else {
|
|
@@ -218,10 +218,8 @@ int cryptodev_cipher_init(struct cipher_
|
|
return 0;
|
|
error:
|
|
if (aead == 0) {
|
|
- if (out->async.request)
|
|
- ablkcipher_request_free(out->async.request);
|
|
- if (out->async.s)
|
|
- crypto_free_ablkcipher(out->async.s);
|
|
+ cryptodev_blkcipher_request_free(out->async.request);
|
|
+ cryptodev_crypto_free_blkcipher(out->async.s);
|
|
} else {
|
|
if (out->async.arequest)
|
|
aead_request_free(out->async.arequest);
|
|
@@ -237,10 +235,8 @@ void cryptodev_cipher_deinit(struct ciph
|
|
{
|
|
if (cdata->init) {
|
|
if (cdata->aead == 0) {
|
|
- if (cdata->async.request)
|
|
- ablkcipher_request_free(cdata->async.request);
|
|
- if (cdata->async.s)
|
|
- crypto_free_ablkcipher(cdata->async.s);
|
|
+ cryptodev_blkcipher_request_free(cdata->async.request);
|
|
+ cryptodev_crypto_free_blkcipher(cdata->async.s);
|
|
} else {
|
|
if (cdata->async.arequest)
|
|
aead_request_free(cdata->async.arequest);
|
|
@@ -289,10 +285,10 @@ ssize_t cryptodev_cipher_encrypt(struct
|
|
reinit_completion(&cdata->async.result->completion);
|
|
|
|
if (cdata->aead == 0) {
|
|
- ablkcipher_request_set_crypt(cdata->async.request,
|
|
+ cryptodev_blkcipher_request_set_crypt(cdata->async.request,
|
|
(struct scatterlist *)src, dst,
|
|
len, cdata->async.iv);
|
|
- ret = crypto_ablkcipher_encrypt(cdata->async.request);
|
|
+ ret = cryptodev_crypto_blkcipher_encrypt(cdata->async.request);
|
|
} else {
|
|
aead_request_set_crypt(cdata->async.arequest,
|
|
(struct scatterlist *)src, dst,
|
|
@@ -311,10 +307,10 @@ ssize_t cryptodev_cipher_decrypt(struct
|
|
|
|
reinit_completion(&cdata->async.result->completion);
|
|
if (cdata->aead == 0) {
|
|
- ablkcipher_request_set_crypt(cdata->async.request,
|
|
+ cryptodev_blkcipher_request_set_crypt(cdata->async.request,
|
|
(struct scatterlist *)src, dst,
|
|
len, cdata->async.iv);
|
|
- ret = crypto_ablkcipher_decrypt(cdata->async.request);
|
|
+ ret = cryptodev_crypto_blkcipher_decrypt(cdata->async.request);
|
|
} else {
|
|
aead_request_set_crypt(cdata->async.arequest,
|
|
(struct scatterlist *)src, dst,
|
|
Index: cryptodev-linux-1.8/cryptlib.h
|
|
===================================================================
|
|
--- cryptodev-linux-1.8.orig/cryptlib.h
|
|
+++ cryptodev-linux-1.8/cryptlib.h
|
|
@@ -3,6 +3,8 @@
|
|
|
|
#include <linux/version.h>
|
|
|
|
+#include "cipherapi.h"
|
|
+
|
|
struct cipher_data {
|
|
int init; /* 0 uninitialized */
|
|
int blocksize;
|
|
@@ -12,8 +14,8 @@ struct cipher_data {
|
|
int alignmask;
|
|
struct {
|
|
/* block ciphers */
|
|
- struct crypto_ablkcipher *s;
|
|
- struct ablkcipher_request *request;
|
|
+ cryptodev_crypto_blkcipher_t *s;
|
|
+ cryptodev_blkcipher_request_t *request;
|
|
|
|
/* AEAD ciphers */
|
|
struct crypto_aead *as;
|
|
Index: cryptodev-linux-1.8/ioctl.c
|
|
===================================================================
|
|
--- cryptodev-linux-1.8.orig/ioctl.c
|
|
+++ cryptodev-linux-1.8/ioctl.c
|
|
@@ -34,7 +34,6 @@
|
|
*/
|
|
|
|
#include <crypto/hash.h>
|
|
-#include <linux/crypto.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/ioctl.h>
|
|
@@ -53,6 +52,7 @@
|
|
#include "cryptodev_int.h"
|
|
#include "zc.h"
|
|
#include "version.h"
|
|
+#include "cipherapi.h"
|
|
|
|
MODULE_AUTHOR("Nikos Mavrogiannopoulos <nmav@gnutls.org>");
|
|
MODULE_DESCRIPTION("CryptoDev driver");
|
|
@@ -765,7 +765,7 @@ static int get_session_info(struct fcryp
|
|
|
|
if (ses_ptr->cdata.init) {
|
|
if (ses_ptr->cdata.aead == 0)
|
|
- tfm = crypto_ablkcipher_tfm(ses_ptr->cdata.async.s);
|
|
+ tfm = cryptodev_crypto_blkcipher_tfm(ses_ptr->cdata.async.s);
|
|
else
|
|
tfm = crypto_aead_tfm(ses_ptr->cdata.async.as);
|
|
tfm_info_to_alg_info(&siop->cipher_info, tfm);
|