1/*
2 * Copyright 2019-2021 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 "prov/ciphercommon.h"
11#include "prov/ciphercommon_ccm.h"
12
13int ossl_ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
14                           size_t nlen, size_t mlen)
15{
16    return CRYPTO_ccm128_setiv(&ctx->ccm_ctx, nonce, nlen, mlen) == 0;
17}
18
19int ossl_ccm_generic_setaad(PROV_CCM_CTX *ctx, const unsigned char *aad,
20                            size_t alen)
21{
22    CRYPTO_ccm128_aad(&ctx->ccm_ctx, aad, alen);
23    return 1;
24}
25
26int ossl_ccm_generic_gettag(PROV_CCM_CTX *ctx, unsigned char *tag, size_t tlen)
27{
28    return CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, tlen) > 0;
29}
30
31int ossl_ccm_generic_auth_encrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
32                                  unsigned char *out, size_t len,
33                                  unsigned char *tag, size_t taglen)
34{
35    int rv;
36
37    if (ctx->str != NULL)
38        rv = CRYPTO_ccm128_encrypt_ccm64(&ctx->ccm_ctx, in,
39                                         out, len, ctx->str) == 0;
40    else
41        rv = CRYPTO_ccm128_encrypt(&ctx->ccm_ctx, in, out, len) == 0;
42
43    if (rv == 1 && tag != NULL)
44        rv = (CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen) > 0);
45    return rv;
46}
47
48int ossl_ccm_generic_auth_decrypt(PROV_CCM_CTX *ctx, const unsigned char *in,
49                                  unsigned char *out, size_t len,
50                                  unsigned char *expected_tag, size_t taglen)
51{
52    int rv = 0;
53
54    if (ctx->str != NULL)
55        rv = CRYPTO_ccm128_decrypt_ccm64(&ctx->ccm_ctx, in, out, len,
56                                         ctx->str) == 0;
57    else
58        rv = CRYPTO_ccm128_decrypt(&ctx->ccm_ctx, in, out, len) == 0;
59    if (rv) {
60        unsigned char tag[16];
61
62        if (!CRYPTO_ccm128_tag(&ctx->ccm_ctx, tag, taglen)
63            || CRYPTO_memcmp(tag, expected_tag, taglen) != 0)
64            rv = 0;
65    }
66    if (rv == 0)
67        OPENSSL_cleanse(out, len);
68    return rv;
69}
70