3036bfaa2e16c0863f439fb147167b71a94abe69
[openssl.git] / providers / common / ciphers / cipher_ccm_hw.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include "cipher_locl.h"
11
12 #define AES_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec)     \
13     fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks);                         \
14     CRYPTO_ccm128_init(&ctx->ccm_ctx, ctx->m, ctx->l, &actx->ccm.ks.ks,        \
15                        (block128_f)fn_blk);                                    \
16     ctx->str = ctx->enc ? (ccm128_f)fn_ccm_enc : (ccm128_f)fn_ccm_dec;         \
17     ctx->key_set = 1;
18
19 static int ccm_generic_aes_initkey(PROV_CCM_CTX *ctx, const unsigned char *key,
20                                    size_t keylen)
21 {
22     PROV_AES_CCM_CTX *actx = (PROV_AES_CCM_CTX *)ctx;
23
24 #ifdef HWAES_CAPABLE
25     if (HWAES_CAPABLE) {
26         AES_CCM_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_encrypt, NULL, NULL);
27     } else
28 #endif /* HWAES_CAPABLE */
29 #ifdef VPAES_CAPABLE
30     if (VPAES_CAPABLE) {
31         AES_CCM_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_encrypt, NULL, NULL);
32     } else
33 #endif
34     {
35         AES_CCM_SET_KEY_FN(AES_set_encrypt_key, AES_encrypt, NULL, NULL)
36     }
37     return 1;
38 }
39
40 static int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
41                              size_t nlen, size_t mlen)
42 {
43     return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0;
44 }
45
46 static int ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad,
47                               size_t alen)
48 {
49     CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen);
50     return 1;
51 }
52
53 static int ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag,
54                               size_t tlen)
55 {
56     return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0;
57 }
58
59 static int ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
60                                     unsigned char *out, size_t len,
61                                     unsigned char *tag, size_t taglen)
62 {
63     int rv;
64
65     if (ctx->str != NULL)
66         rv = CRYPTO_ccm128_encrypt_ccm64(&ctx->ccm_ctx, in,
67                                          out, len, ctx->str) == 0;
68     else
69         rv = CRYPTO_ccm128_encrypt(&ctx->ccm_ctx, in, out, len) == 0;
70
71     if (rv == 1 && tag != NULL)
72         rv = (CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen) > 0);
73     return rv;
74 }
75
76 static int ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
77                                     unsigned char *out, size_t len,
78                                     unsigned char *expected_tag,
79                                     size_t taglen)
80 {
81     int rv = 0;
82
83     if (ctx->str != NULL)
84         rv = CRYPTO_ccm128_decrypt_ccm64(&ctx->ccm_ctx, in, out, len,
85                                          ctx->str) == 0;
86     else
87         rv = CRYPTO_ccm128_decrypt(&ctx->ccm_ctx, in, out, len) == 0;
88     if (rv) {
89         unsigned char tag[16];
90
91         if (!CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen)
92             || CRYPTO_memcmp(tag, expected_tag, taglen) != 0)
93             rv = 0;
94     }
95     if (rv == 0)
96         OPENSSL_cleanse(out, len);
97     return rv;
98 }
99
100 static const PROV_CCM_HW aes_ccm = {
101     ccm_generic_aes_initkey,
102     ccm_generic_setiv,
103     ccm_generic_setaad,
104     ccm_generic_auth_encrypt,
105     ccm_generic_auth_decrypt,
106     ccm_generic_gettag
107 };
108 #if defined(S390X_aes_128_CAPABLE)
109 # include "cipher_aes_ccm_hw_s390x.inc"
110 #elif defined(AESNI_CAPABLE)
111 # include "cipher_aes_ccm_hw_aesni.inc"
112 #elif defined(SPARC_AES_CAPABLE)
113 # include "cipher_aes_ccm_hw_t4.inc"
114 #else
115 const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits)
116 {
117     return &aes_ccm;
118 }
119 #endif
120
121 #include "cipher_aria_ccm_hw.inc"