1155324Simp/*
2155324Simp * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3155324Simp *
4155324Simp * Licensed under the Apache License 2.0 (the "License").  You may not use
5155324Simp * this file except in compliance with the License.  You can obtain a copy
6155324Simp * in the file LICENSE in the source distribution or at
7155324Simp * https://www.openssl.org/source/license.html
8155324Simp */
9155324Simp
10155324Simp#include "prov/ciphercommon.h"
11155324Simp#include "prov/ciphercommon_ccm.h"
12155324Simp
13185265Simpint ossl_ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
14185265Simp                           size_t nlen, size_t mlen)
15185265Simp{
16185265Simp    return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0;
17185265Simp}
18185265Simp
19185265Simpint ossl_ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad,
20185265Simp                            size_t alen)
21185265Simp{
22185265Simp    CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen);
23185265Simp    return 1;
24155324Simp}
25155324Simp
26155324Simpint ossl_ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen)
27155324Simp{
28155324Simp    return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0;
29155324Simp}
30155324Simp
31213496Scognetint ossl_ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
32155324Simp                                  unsigned char *out, size_t len,
33155324Simp                                  unsigned char *tag, size_t taglen)
34213496Scognet{
35213496Scognet    int rv;
36155324Simp
37155324Simp    if (ctx->str != NULL)
38155324Simp        rv = CRYPTO_ccm128_encrypt_ccm64(&ctx->ccm_ctx, in,
39155324Simp                                         out, len, ctx->str) == 0;
40213496Scognet    else
41155324Simp        rv = CRYPTO_ccm128_encrypt(&ctx->ccm_ctx, in, out, len) == 0;
42155324Simp
43155324Simp    if (rv == 1 && tag != NULL)
44155324Simp        rv = (CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen) > 0);
45155324Simp    return rv;
46155324Simp}
47155324Simp
48155324Simpint ossl_ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
49213496Scognet                                  unsigned char *out, size_t len,
50213496Scognet                                  unsigned char *expected_tag, size_t taglen)
51213496Scognet{
52213496Scognet    int rv = 0;
53213496Scognet
54213496Scognet    if (ctx->str != NULL)
55213496Scognet        rv = CRYPTO_ccm128_decrypt_ccm64(&ctx->ccm_ctx, in, out, len,
56213496Scognet                                         ctx->str) == 0;
57213496Scognet    else
58213496Scognet        rv = CRYPTO_ccm128_decrypt(&ctx->ccm_ctx, in, out, len) == 0;
59213496Scognet    if (rv) {
60213496Scognet        unsigned char tag[16];
61236658Simp
62236658Simp        if (!CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen)
63236658Simp            || CRYPTO_memcmp(tag, expected_tag, taglen) != 0)
64236658Simp            rv = 0;
65236658Simp    }
66236658Simp    if (rv == 0)
67236658Simp        OPENSSL_cleanse(out, len);
68236658Simp    return rv;
69236658Simp}
70236658Simp