1 /* SPDX-License-Identifier: GPL-2.0+ */
2
3 #ifndef CRYPTLIB_H
4 # define CRYPTLIB_H
5
6 #include <linux/version.h>
7
8 struct cryptodev_result {
9 struct completion completion;
10 int err;
11 };
12
13 #include "cipherapi.h"
14
15 struct cipher_data {
16 int init; /* 0 uninitialized */
17 int blocksize;
18 int aead;
19 int stream;
20 int ivsize;
21 int alignmask;
22 struct {
23 /* block ciphers */
24 cryptodev_crypto_blkcipher_t *s;
25 cryptodev_blkcipher_request_t *request;
26
27 /* AEAD ciphers */
28 struct crypto_aead *as;
29 struct aead_request *arequest;
30
31 struct cryptodev_result result;
32 uint8_t iv[EALG_MAX_BLOCK_LEN];
33 } async;
34 };
35
36 int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name,
37 uint8_t *key, size_t keylen, int stream, int aead);
38 void cryptodev_cipher_deinit(struct cipher_data *cdata);
39 int cryptodev_get_cipher_key(uint8_t *key, struct session_op *sop, int aead);
40 int cryptodev_get_cipher_keylen(unsigned int *keylen, struct session_op *sop,
41 int aead);
42 ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata,
43 const struct scatterlist *sg1,
44 struct scatterlist *sg2, size_t len);
45 ssize_t cryptodev_cipher_encrypt(struct cipher_data *cdata,
46 const struct scatterlist *sg1,
47 struct scatterlist *sg2, size_t len);
48
49 /* AEAD */
cryptodev_cipher_auth(struct cipher_data * cdata,struct scatterlist * sg1,size_t len)50 static inline void cryptodev_cipher_auth(struct cipher_data *cdata,
51 struct scatterlist *sg1, size_t len)
52 {
53 /* for some reason we _have_ to call that even for zero length sgs */
54 #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0))
55 aead_request_set_assoc(cdata->async.arequest, len ? sg1 : NULL, len);
56 #else
57 aead_request_set_ad(cdata->async.arequest, len);
58 #endif
59 }
60
cryptodev_cipher_set_tag_size(struct cipher_data * cdata,int size)61 static inline void cryptodev_cipher_set_tag_size(struct cipher_data *cdata, int size)
62 {
63 if (likely(cdata->aead != 0))
64 crypto_aead_setauthsize(cdata->async.as, size);
65 }
66
cryptodev_cipher_get_tag_size(struct cipher_data * cdata)67 static inline int cryptodev_cipher_get_tag_size(struct cipher_data *cdata)
68 {
69 if (likely(cdata->init && cdata->aead != 0))
70 return crypto_aead_authsize(cdata->async.as);
71 else
72 return 0;
73 }
74
cryptodev_cipher_set_iv(struct cipher_data * cdata,void * iv,size_t iv_size)75 static inline void cryptodev_cipher_set_iv(struct cipher_data *cdata,
76 void *iv, size_t iv_size)
77 {
78 memcpy(cdata->async.iv, iv, min(iv_size, sizeof(cdata->async.iv)));
79 }
80
cryptodev_cipher_get_iv(struct cipher_data * cdata,void * iv,size_t iv_size)81 static inline void cryptodev_cipher_get_iv(struct cipher_data *cdata,
82 void *iv, size_t iv_size)
83 {
84 memcpy(iv, cdata->async.iv, min(iv_size, sizeof(cdata->async.iv)));
85 }
86
87 /* Hash */
88 struct hash_data {
89 int init; /* 0 uninitialized */
90 int digestsize;
91 int alignmask;
92 struct {
93 struct crypto_ahash *s;
94 struct cryptodev_result result;
95 struct ahash_request *request;
96 } async;
97 };
98
99 int cryptodev_hash_final(struct hash_data *hdata, void *output);
100 ssize_t cryptodev_hash_update(struct hash_data *hdata,
101 struct scatterlist *sg, size_t len);
102 int cryptodev_hash_reset(struct hash_data *hdata);
103 void cryptodev_hash_deinit(struct hash_data *hdata);
104 int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name,
105 int hmac_mode, void *mackey, size_t mackeylen);
106 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
107 int cryptodev_hash_copy(struct hash_data *dst, struct hash_data *src);
108 #endif
109
110
111 #endif
112