]> code.ossystems Code Review - meta-freescale.git/blob
499df59bf9651a1a059f0bdc2105e72142a6f180
[meta-freescale.git] /
1 From 501988587567b996c9c4a14239f575e77ed27791 Mon Sep 17 00:00:00 2001
2 From: Pankaj Gupta <pankaj.gupta@nxp.com>
3 Date: Fri, 20 Sep 2019 12:18:16 +0530
4 Subject: [PATCH 1/2] eng_devcrypto: add support for TLS algorithms offload
5
6     - aes-128-cbc-hmac-sha1
7     - aes-256-cbc-hmac-sha1
8
9 Requires TLS patches on cryptodev and TLS algorithm support in Linux
10 kernel driver.
11
12 Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
13 ---
14  crypto/engine/eng_devcrypto.c | 265 +++++++++++++++++++++++++++++-----
15  1 file changed, 231 insertions(+), 34 deletions(-)
16
17 diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c
18 index 49e9ce1af3..727a660e75 100644
19 --- a/crypto/engine/eng_devcrypto.c
20 +++ b/crypto/engine/eng_devcrypto.c
21 @@ -60,6 +60,9 @@ struct cipher_ctx {
22      struct session_op sess;
23      int op;                      /* COP_ENCRYPT or COP_DECRYPT */
24      unsigned long mode;          /* EVP_CIPH_*_MODE */
25 +    unsigned char *aad;
26 +    unsigned int aad_len;
27 +    unsigned int len;
28  
29      /* to handle ctr mode being a stream cipher */
30      unsigned char partial[EVP_MAX_BLOCK_LENGTH];
31 @@ -73,49 +76,62 @@ static const struct cipher_data_st {
32      int ivlen;
33      int flags;
34      int devcryptoid;
35 +    int mackeylen;
36  } cipher_data[] = {
37  #ifndef OPENSSL_NO_DES
38 -    { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
39 -    { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
40 +    { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC, 0 },
41 +    { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC, 0 },
42  #endif
43  #ifndef OPENSSL_NO_BF
44 -    { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
45 +    { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC, 0 },
46  #endif
47  #ifndef OPENSSL_NO_CAST
48 -    { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
49 +    { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC, 0 },
50  #endif
51 -    { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
52 -    { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
53 -    { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
54 +    { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
55 +    { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
56 +    { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
57 +    { NID_aes_128_cbc_hmac_sha1, 16, 16, 16,
58 +           EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
59 +           CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 },
60 +    { NID_aes_256_cbc_hmac_sha1, 16, 32, 16,
61 +           EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
62 +           CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 },
63  #ifndef OPENSSL_NO_RC4
64 -    { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
65 +    { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4, 0 },
66  #endif
67  #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
68 -    { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
69 -    { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
70 -    { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
71 +    { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
72 +    { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
73 +    { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
74  #endif
75  #if 0                            /* Not yet supported */
76 -    { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
77 -    { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
78 +    { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS,
79 +           0 },
80 +    { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS,
81 +           0 },
82  #endif
83  #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
84 -    { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
85 -    { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
86 -    { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
87 +    { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
88 +    { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
89 +    { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
90  #endif
91  #if 0                            /* Not yet supported */
92 -    { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
93 -    { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
94 -    { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
95 +    { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
96 +    { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
97 +    { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
98 +#endif
99 +#ifdef OPENSSL_NXP_CAAM
100 +    { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
101 +    { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
102  #endif
103  #ifndef OPENSSL_NO_CAMELLIA
104      { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
105 -      CRYPTO_CAMELLIA_CBC },
106 +      CRYPTO_CAMELLIA_CBC, 0 },
107      { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
108 -      CRYPTO_CAMELLIA_CBC },
109 +      CRYPTO_CAMELLIA_CBC, 0 },
110      { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
111 -      CRYPTO_CAMELLIA_CBC },
112 +      CRYPTO_CAMELLIA_CBC, 0 },
113  #endif
114  };
115  
116 @@ -141,6 +157,158 @@ static const struct cipher_data_st *get_cipher_data(int nid)
117      return &cipher_data[get_cipher_data_index(nid)];
118  }
119  
120 +/*
121 + * Save the encryption key provided by upper layers. This function is called
122 + * by EVP_CipherInit_ex to initialize the algorithm's extra data. We can't do
123 + * much here because the mac key is not available. The next call should/will
124 + * be to cryptodev_cbc_hmac_sha1_ctrl with parameter
125 + * EVP_CTRL_AEAD_SET_MAC_KEY, to set the hmac key. There we call CIOCGSESSION
126 + * with both the crypto and hmac keys.
127 + */
128 +static int cryptodev_init_aead_key(EVP_CIPHER_CTX *ctx,
129 +               const unsigned char *key, const unsigned char *iv, int enc)
130 +{
131 +    struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
132 +    struct session_op *sess = &state->sess;
133 +    int cipher = -1, i;
134 +
135 +    for (i = 0; cipher_data[i].devcryptoid; i++) {
136 +        if (EVP_CIPHER_CTX_nid(ctx) == cipher_data[i].nid &&
137 +            EVP_CIPHER_CTX_iv_length(ctx) <= cipher_data[i].ivlen &&
138 +            EVP_CIPHER_CTX_key_length(ctx) == cipher_data[i].keylen) {
139 +            cipher = cipher_data[i].devcryptoid;
140 +            break;
141 +        }
142 +    }
143 +
144 +    if (!cipher_data[i].devcryptoid)
145 +        return (0);
146 +
147 +    memset(sess, 0, sizeof(*sess));
148 +
149 +    sess->key = (void *) key;
150 +    sess->keylen = EVP_CIPHER_CTX_key_length(ctx);
151 +    sess->cipher = cipher;
152 +
153 +    /* for whatever reason, (1) means success */
154 +    return 1;
155 +}
156 +
157 +static int cryptodev_aead_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
158 +                                 const unsigned char *in, size_t len)
159 +{
160 +    struct crypt_auth_op cryp;
161 +    struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
162 +    struct session_op *sess = &state->sess;
163 +    const void *iiv;
164 +    unsigned char save_iv[EVP_MAX_IV_LENGTH];
165 +
166 +    if (cfd < 0)
167 +        return (0);
168 +    if (!len)
169 +        return (1);
170 +    if ((len % EVP_CIPHER_CTX_block_size(ctx)) != 0)
171 +        return (0);
172 +
173 +    memset(&cryp, 0, sizeof(cryp));
174 +
175 +    /* TODO: make a seamless integration with cryptodev flags */
176 +    switch (EVP_CIPHER_CTX_nid(ctx)) {
177 +    case NID_aes_128_cbc_hmac_sha1:
178 +    case NID_aes_256_cbc_hmac_sha1:
179 +        cryp.flags = COP_FLAG_AEAD_TLS_TYPE;
180 +    }
181 +    cryp.ses = sess->ses;
182 +    cryp.len = state->len;
183 +    cryp.src = (void *) in;
184 +    cryp.dst = (void *) out;
185 +    cryp.auth_src = state->aad;
186 +    cryp.auth_len = state->aad_len;
187 +
188 +    cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
189 +
190 +    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
191 +        cryp.iv = (void *) EVP_CIPHER_CTX_iv(ctx);
192 +        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
193 +            iiv = in + len - EVP_CIPHER_CTX_iv_length(ctx);
194 +            memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx));
195 +        }
196 +    } else
197 +        cryp.iv = NULL;
198 +
199 +    if (ioctl(cfd, CIOCAUTHCRYPT, &cryp) == -1) {
200 +        /*
201 +         * XXX need better errror handling this can fail for a number of
202 +         * different reasons.
203 +         */
204 +        return 0;
205 +    }
206 +
207 +    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
208 +        if (EVP_CIPHER_CTX_encrypting(ctx))
209 +            iiv = out + len - EVP_CIPHER_CTX_iv_length(ctx);
210 +        else
211 +            iiv = save_iv;
212 +
213 +        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv,
214 +               EVP_CIPHER_CTX_iv_length(ctx));
215 +    }
216 +    return 1;
217 +}
218 +
219 +static int cryptodev_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
220 +                                        int arg, void *ptr)
221 +{
222 +    switch (type) {
223 +    case EVP_CTRL_AEAD_SET_MAC_KEY:
224 +        {
225 +       /* TODO: what happens with hmac keys larger than 64 bytes? */
226 +            struct cipher_ctx *state =
227 +                EVP_CIPHER_CTX_get_cipher_data(ctx);
228 +            struct session_op *sess = &state->sess;
229 +
230 +            /* the rest should have been set in cryptodev_init_aead_key */
231 +            sess->mackey = ptr;
232 +            sess->mackeylen = arg;
233 +            if (ioctl(cfd, CIOCGSESSION, sess) == -1)
234 +                return 0;
235 +
236 +            return 1;
237 +        }
238 +    case EVP_CTRL_AEAD_TLS1_AAD:
239 +        {
240 +            /* ptr points to the associated data buffer of 13 bytes */
241 +            struct cipher_ctx *state =
242 +                EVP_CIPHER_CTX_get_cipher_data(ctx);
243 +            unsigned char *p = ptr;
244 +            unsigned int cryptlen = p[arg - 2] << 8 | p[arg - 1];
245 +            unsigned int maclen, padlen;
246 +            unsigned int bs = EVP_CIPHER_CTX_block_size(ctx);
247 +
248 +            state->aad = ptr;
249 +            state->aad_len = arg;
250 +            state->len = cryptlen;
251 +
252 +            /* TODO: this should be an extension of EVP_CIPHER struct */
253 +            switch (EVP_CIPHER_CTX_nid(ctx)) {
254 +            case NID_aes_128_cbc_hmac_sha1:
255 +            case NID_aes_256_cbc_hmac_sha1:
256 +                maclen = SHA_DIGEST_LENGTH;
257 +            }
258 +
259 +            /* space required for encryption (not only TLS padding) */
260 +            padlen = maclen;
261 +            if (EVP_CIPHER_CTX_encrypting(ctx)) {
262 +                cryptlen += maclen;
263 +                padlen += bs - (cryptlen % bs);
264 +            }
265 +            return padlen;
266 +        }
267 +    default:
268 +        return -1;
269 +    }
270 +}
271 +
272  /*
273   * Following are the three necessary functions to map OpenSSL functionality
274   * with cryptodev.
275 @@ -165,6 +333,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
276      cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
277      cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
278      cipher_ctx->blocksize = cipher_d->blocksize;
279 +
280      if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
281          SYSerr(SYS_F_IOCTL, errno);
282          return 0;
283 @@ -180,6 +349,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
284          (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
285      struct crypt_op cryp;
286      unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
287 +
288  #if !defined(COP_FLAG_WRITE_IV)
289      unsigned char saved_iv[EVP_MAX_IV_LENGTH];
290      const unsigned char *ivptr;
291 @@ -340,32 +510,59 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
292  static int known_cipher_nids[OSSL_NELEM(cipher_data)];
293  static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
294  static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
295 +int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
296 +               const unsigned char *iv, int enc);
297 +int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
298 +               const unsigned char *in, size_t inl);
299 +int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
300  
301  static void prepare_cipher_methods(void)
302  {
303      size_t i;
304      struct session_op sess;
305      unsigned long cipher_mode;
306 +    unsigned long flags;
307  
308      memset(&sess, 0, sizeof(sess));
309      sess.key = (void *)"01234567890123456789012345678901234567890123456789";
310 +    sess.mackey = (void *)"123456789ABCDEFGHIJKLMNO";
311  
312      for (i = 0, known_cipher_nids_amount = 0;
313           i < OSSL_NELEM(cipher_data); i++) {
314  
315 +        init  = cipher_init;
316 +        ctrl  = cipher_ctrl;
317 +        flags = cipher_data[i].flags
318 +                | EVP_CIPH_CUSTOM_COPY
319 +                | EVP_CIPH_CTRL_INIT
320 +                | EVP_CIPH_FLAG_DEFAULT_ASN1;
321 +
322          /*
323           * Check that the algo is really availably by trying to open and close
324           * a session.
325           */
326          sess.cipher = cipher_data[i].devcryptoid;
327          sess.keylen = cipher_data[i].keylen;
328 +       sess.mackeylen = cipher_data[i].mackeylen;
329 +
330 +        cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
331 +
332 +       do_cipher = (cipher_mode == EVP_CIPH_CTR_MODE ?
333 +                                              ctr_do_cipher :
334 +                                              cipher_do_cipher);
335 +       if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1
336 +               || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1) {
337 +               init = cryptodev_init_aead_key;
338 +               do_cipher = cryptodev_aead_cipher;
339 +               ctrl = cryptodev_cbc_hmac_sha1_ctrl;
340 +               flags = cipher_data[i].flags;
341 +       }
342 +
343          if (ioctl(cfd, CIOCGSESSION, &sess) < 0
344              || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
345              continue;
346  
347 -        cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
348 -
349 -        if ((known_cipher_methods[i] =
350 +       if ((known_cipher_methods[i] =
351                   EVP_CIPHER_meth_new(cipher_data[i].nid,
352                                       cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
353                                                      cipher_data[i].blocksize,
354 @@ -373,16 +570,12 @@ static void prepare_cipher_methods(void)
355              || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
356                                                cipher_data[i].ivlen)
357              || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
358 -                                          cipher_data[i].flags
359 -                                          | EVP_CIPH_CUSTOM_COPY
360 -                                          | EVP_CIPH_CTRL_INIT
361 -                                          | EVP_CIPH_FLAG_DEFAULT_ASN1)
362 -            || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
363 +                                          flags)
364 +            || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], init)
365              || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
366 -                                     cipher_mode == EVP_CIPH_CTR_MODE ?
367 -                                              ctr_do_cipher :
368 -                                              cipher_do_cipher)
369 -            || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
370 +                                              do_cipher)
371 +           /* AEAD Support to be added. */
372 +            || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], ctrl)
373              || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
374                                              cipher_cleanup)
375              || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
376 @@ -393,6 +586,10 @@ static void prepare_cipher_methods(void)
377              known_cipher_nids[known_cipher_nids_amount++] =
378                  cipher_data[i].nid;
379          }
380 +
381 +       if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1
382 +               || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1)
383 +               EVP_add_cipher(known_cipher_methods[i]);
384      }
385  }
386  
387 -- 
388 2.17.1
389