]> code.ossystems Code Review - meta-freescale.git/blob
d5907892801087358845053f14f025d02852baed
[meta-freescale.git] /
1 From e7c630f8417b6f4e1bf2466e545ffe04af2eff00 Mon Sep 17 00:00:00 2001
2 From: Cristian Stoica <cristian.stoica@freescale.com>
3 Date: Thu, 29 Aug 2013 16:51:18 +0300
4 Subject: [PATCH 02/48] eng_cryptodev: 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: Cristian Stoica <cristian.stoica@freescale.com>
13 ---
14  crypto/engine/eng_cryptodev.c | 226 ++++++++++++++++++++++++++++++++++++++++--
15  1 file changed, 215 insertions(+), 11 deletions(-)
16
17 diff --git a/crypto/engine/eng_cryptodev.c b/crypto/engine/eng_cryptodev.c
18 index 8fb9c33..4d783d4 100644
19 --- a/crypto/engine/eng_cryptodev.c
20 +++ b/crypto/engine/eng_cryptodev.c
21 @@ -71,6 +71,9 @@ void ENGINE_load_cryptodev(void)
22  struct dev_crypto_state {
23      struct session_op d_sess;
24      int d_fd;
25 +    unsigned char *aad;
26 +    unsigned int aad_len;
27 +    unsigned int len;
28  # ifdef USE_CRYPTODEV_DIGESTS
29      char dummy_mac_key[HASH_MAX_LEN];
30      unsigned char digest_res[HASH_MAX_LEN];
31 @@ -141,24 +144,25 @@ static struct {
32      int nid;
33      int ivmax;
34      int keylen;
35 +    int mackeylen;
36  } ciphers[] = {
37      {
38 -        CRYPTO_ARC4, NID_rc4, 0, 16,
39 +        CRYPTO_ARC4, NID_rc4, 0, 16, 0
40      },
41      {
42 -        CRYPTO_DES_CBC, NID_des_cbc, 8, 8,
43 +        CRYPTO_DES_CBC, NID_des_cbc, 8, 8, 0
44      },
45      {
46 -        CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24,
47 +        CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, 0
48      },
49      {
50 -        CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16,
51 +        CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, 0
52      },
53      {
54 -        CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24,
55 +        CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, 0
56      },
57      {
58 -        CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32,
59 +        CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, 0
60      },
61  # ifdef CRYPTO_AES_CTR
62      {
63 @@ -172,16 +176,22 @@ static struct {
64      },
65  # endif
66      {
67 -        CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16,
68 +        CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, 0
69      },
70      {
71 -        CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16,
72 +        CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, 0
73      },
74      {
75 -        CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0,
76 +        CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, 0
77      },
78      {
79 -        0, NID_undef, 0, 0,
80 +        CRYPTO_TLS10_AES_CBC_HMAC_SHA1, NID_aes_128_cbc_hmac_sha1, 16, 16, 20
81 +    },
82 +    {
83 +        CRYPTO_TLS10_AES_CBC_HMAC_SHA1, NID_aes_256_cbc_hmac_sha1, 16, 32, 20
84 +    },
85 +    {
86 +        0, NID_undef, 0, 0, 0
87      },
88  };
89  
90 @@ -295,13 +305,15 @@ static int get_cryptodev_ciphers(const int **cnids)
91      }
92      memset(&sess, 0, sizeof(sess));
93      sess.key = (caddr_t) "123456789abcdefghijklmno";
94 +    sess.mackey = (caddr_t) "123456789ABCDEFGHIJKLMNO";
95  
96      for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
97          if (ciphers[i].nid == NID_undef)
98              continue;
99          sess.cipher = ciphers[i].id;
100          sess.keylen = ciphers[i].keylen;
101 -        sess.mac = 0;
102 +        sess.mackeylen = ciphers[i].mackeylen;
103 +
104          if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
105              ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
106              nids[count++] = ciphers[i].nid;
107 @@ -457,6 +469,66 @@ cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
108      return (1);
109  }
110  
111 +static int cryptodev_aead_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
112 +                                 const unsigned char *in, size_t len)
113 +{
114 +    struct crypt_auth_op cryp;
115 +    struct dev_crypto_state *state = ctx->cipher_data;
116 +    struct session_op *sess = &state->d_sess;
117 +    const void *iiv;
118 +    unsigned char save_iv[EVP_MAX_IV_LENGTH];
119 +
120 +    if (state->d_fd < 0)
121 +        return (0);
122 +    if (!len)
123 +        return (1);
124 +    if ((len % ctx->cipher->block_size) != 0)
125 +        return (0);
126 +
127 +    memset(&cryp, 0, sizeof(cryp));
128 +
129 +    /* TODO: make a seamless integration with cryptodev flags */
130 +    switch (ctx->cipher->nid) {
131 +    case NID_aes_128_cbc_hmac_sha1:
132 +    case NID_aes_256_cbc_hmac_sha1:
133 +        cryp.flags = COP_FLAG_AEAD_TLS_TYPE;
134 +    }
135 +    cryp.ses = sess->ses;
136 +    cryp.len = state->len;
137 +    cryp.src = (caddr_t) in;
138 +    cryp.dst = (caddr_t) out;
139 +    cryp.auth_src = state->aad;
140 +    cryp.auth_len = state->aad_len;
141 +
142 +    cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
143 +
144 +    if (ctx->cipher->iv_len) {
145 +        cryp.iv = (caddr_t) ctx->iv;
146 +        if (!ctx->encrypt) {
147 +            iiv = in + len - ctx->cipher->iv_len;
148 +            memcpy(save_iv, iiv, ctx->cipher->iv_len);
149 +        }
150 +    } else
151 +        cryp.iv = NULL;
152 +
153 +    if (ioctl(state->d_fd, CIOCAUTHCRYPT, &cryp) == -1) {
154 +        /*
155 +         * XXX need better errror handling this can fail for a number of
156 +         * different reasons.
157 +         */
158 +        return (0);
159 +    }
160 +
161 +    if (ctx->cipher->iv_len) {
162 +        if (ctx->encrypt)
163 +            iiv = out + len - ctx->cipher->iv_len;
164 +        else
165 +            iiv = save_iv;
166 +        memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
167 +    }
168 +    return (1);
169 +}
170 +
171  static int
172  cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
173                     const unsigned char *iv, int enc)
174 @@ -496,6 +568,45 @@ cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
175  }
176  
177  /*
178 + * Save the encryption key provided by upper layers. This function is called
179 + * by EVP_CipherInit_ex to initialize the algorithm's extra data. We can't do
180 + * much here because the mac key is not available. The next call should/will
181 + * be to cryptodev_cbc_hmac_sha1_ctrl with parameter
182 + * EVP_CTRL_AEAD_SET_MAC_KEY, to set the hmac key. There we call CIOCGSESSION
183 + * with both the crypto and hmac keys.
184 + */
185 +static int cryptodev_init_aead_key(EVP_CIPHER_CTX *ctx,
186 +                                   const unsigned char *key,
187 +                                   const unsigned char *iv, int enc)
188 +{
189 +    struct dev_crypto_state *state = ctx->cipher_data;
190 +    struct session_op *sess = &state->d_sess;
191 +    int cipher = -1, i;
192 +
193 +    for (i = 0; ciphers[i].id; i++)
194 +        if (ctx->cipher->nid == ciphers[i].nid &&
195 +            ctx->cipher->iv_len <= ciphers[i].ivmax &&
196 +            ctx->key_len == ciphers[i].keylen) {
197 +            cipher = ciphers[i].id;
198 +            break;
199 +        }
200 +
201 +    if (!ciphers[i].id) {
202 +        state->d_fd = -1;
203 +        return (0);
204 +    }
205 +
206 +    memset(sess, 0, sizeof(struct session_op));
207 +
208 +    sess->key = (caddr_t) key;
209 +    sess->keylen = ctx->key_len;
210 +    sess->cipher = cipher;
211 +
212 +    /* for whatever reason, (1) means success */
213 +    return (1);
214 +}
215 +
216 +/*
217   * free anything we allocated earlier when initting a
218   * session, and close the session.
219   */
220 @@ -529,6 +640,63 @@ static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
221      return (ret);
222  }
223  
224 +static int cryptodev_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
225 +                                        int arg, void *ptr)
226 +{
227 +    switch (type) {
228 +    case EVP_CTRL_AEAD_SET_MAC_KEY:
229 +        {
230 +            /* TODO: what happens with hmac keys larger than 64 bytes? */
231 +            struct dev_crypto_state *state = ctx->cipher_data;
232 +            struct session_op *sess = &state->d_sess;
233 +
234 +            if ((state->d_fd = get_dev_crypto()) < 0)
235 +                return (0);
236 +
237 +            /* the rest should have been set in cryptodev_init_aead_key */
238 +            sess->mackey = ptr;
239 +            sess->mackeylen = arg;
240 +
241 +            if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
242 +                put_dev_crypto(state->d_fd);
243 +                state->d_fd = -1;
244 +                return (0);
245 +            }
246 +            return (1);
247 +        }
248 +    case EVP_CTRL_AEAD_TLS1_AAD:
249 +        {
250 +            /* ptr points to the associated data buffer of 13 bytes */
251 +            struct dev_crypto_state *state = ctx->cipher_data;
252 +            unsigned char *p = ptr;
253 +            unsigned int cryptlen = p[arg - 2] << 8 | p[arg - 1];
254 +            unsigned int maclen, padlen;
255 +            unsigned int bs = ctx->cipher->block_size;
256 +
257 +            state->aad = ptr;
258 +            state->aad_len = arg;
259 +            state->len = cryptlen;
260 +
261 +            /* TODO: this should be an extension of EVP_CIPHER struct */
262 +            switch (ctx->cipher->nid) {
263 +            case NID_aes_128_cbc_hmac_sha1:
264 +            case NID_aes_256_cbc_hmac_sha1:
265 +                maclen = SHA_DIGEST_LENGTH;
266 +            }
267 +
268 +            /* space required for encryption (not only TLS padding) */
269 +            padlen = maclen;
270 +            if (ctx->encrypt) {
271 +                cryptlen += maclen;
272 +                padlen += bs - (cryptlen % bs);
273 +            }
274 +            return padlen;
275 +        }
276 +    default:
277 +        return -1;
278 +    }
279 +}
280 +
281  /*
282   * libcrypto EVP stuff - this is how we get wired to EVP so the engine
283   * gets called when libcrypto requests a cipher NID.
284 @@ -641,6 +809,34 @@ const EVP_CIPHER cryptodev_aes_256_cbc = {
285      NULL
286  };
287  
288 +const EVP_CIPHER cryptodev_aes_128_cbc_hmac_sha1 = {
289 +    NID_aes_128_cbc_hmac_sha1,
290 +    16, 16, 16,
291 +    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
292 +    cryptodev_init_aead_key,
293 +    cryptodev_aead_cipher,
294 +    cryptodev_cleanup,
295 +    sizeof(struct dev_crypto_state),
296 +    EVP_CIPHER_set_asn1_iv,
297 +    EVP_CIPHER_get_asn1_iv,
298 +    cryptodev_cbc_hmac_sha1_ctrl,
299 +    NULL
300 +};
301 +
302 +const EVP_CIPHER cryptodev_aes_256_cbc_hmac_sha1 = {
303 +    NID_aes_256_cbc_hmac_sha1,
304 +    16, 32, 16,
305 +    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
306 +    cryptodev_init_aead_key,
307 +    cryptodev_aead_cipher,
308 +    cryptodev_cleanup,
309 +    sizeof(struct dev_crypto_state),
310 +    EVP_CIPHER_set_asn1_iv,
311 +    EVP_CIPHER_get_asn1_iv,
312 +    cryptodev_cbc_hmac_sha1_ctrl,
313 +    NULL
314 +};
315 +
316  # ifdef CRYPTO_AES_CTR
317  const EVP_CIPHER cryptodev_aes_ctr = {
318      NID_aes_128_ctr,
319 @@ -729,6 +925,12 @@ cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
320          *cipher = &cryptodev_aes_ctr_256;
321          break;
322  # endif
323 +    case NID_aes_128_cbc_hmac_sha1:
324 +        *cipher = &cryptodev_aes_128_cbc_hmac_sha1;
325 +        break;
326 +    case NID_aes_256_cbc_hmac_sha1:
327 +        *cipher = &cryptodev_aes_256_cbc_hmac_sha1;
328 +        break;
329      default:
330          *cipher = NULL;
331          break;
332 @@ -1472,6 +1674,8 @@ void ENGINE_load_cryptodev(void)
333      }
334      put_dev_crypto(fd);
335  
336 +    EVP_add_cipher(&cryptodev_aes_128_cbc_hmac_sha1);
337 +    EVP_add_cipher(&cryptodev_aes_256_cbc_hmac_sha1);
338      if (!ENGINE_set_id(engine, "cryptodev") ||
339          !ENGINE_set_name(engine, "BSD cryptodev engine") ||
340          !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
341 -- 
342 2.7.0
343