static int ccm_tls_cipher(PROV_CCM_CTX *ctx,
                          unsigned char *out, size_t *padlen,
                          const unsigned char *in, size_t len)
{
    int rv = 0;
    size_t olen = 0;
    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)ctx->m))
        goto err;
    if (ctx->enc)
        memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN);
    memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN);
    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;
    if (!ccm_set_iv(ctx, len))
        goto err;
    if (!ctx->hw->setaad(ctx, ctx->buf, ctx->tls_aad_len))
        goto err;
    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
    if (ctx->enc) {
        if (!ctx->hw->auth_encrypt(ctx, in, out, len,  out + len, ctx->m))
            goto err;
        olen = len + EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;
    } else {
        if (!ctx->hw->auth_decrypt(ctx, in, out, len,
                                   (unsigned char *)in + len, ctx->m))
            goto err;
        olen = len;
    }
    rv = 1;
err:
    *padlen = olen;
    return rv;
}
['int ccm_stream_final(void *vctx, unsigned char *out, size_t *outl,\n                            size_t outsize)\n{\n    PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx;\n    int i;\n    i = ccm_cipher_internal(ctx, out, outl, NULL, 0);\n    if (i <= 0)\n        return 0;\n    *outl = 0;\n    return 1;\n}', 'static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,\n                               size_t *padlen, const unsigned char *in,\n                               size_t len)\n{\n    int rv = 0;\n    size_t olen = 0;\n    const PROV_CCM_HW *hw = ctx->hw;\n    if (!ctx->key_set)\n        return 0;\n    if (ctx->tls_aad_len >= 0)\n        return ccm_tls_cipher(ctx, out, padlen, in, len);\n    if (in == NULL && out != NULL)\n        return 1;\n    if (!ctx->iv_set)\n        goto err;\n    if (out == NULL) {\n        if (in == NULL) {\n            if (!ccm_set_iv(ctx, len))\n                goto err;\n        } else {\n            if (!ctx->len_set && len)\n                goto err;\n            if (!hw->setaad(ctx, in, len))\n                goto err;\n        }\n    } else {\n        if (!ctx->len_set && !ccm_set_iv(ctx, len))\n            goto err;\n        if (ctx->enc) {\n            if (!hw->auth_encrypt(ctx, in, out, len, NULL, 0))\n                goto err;\n            ctx->tag_set = 1;\n        } else {\n            if (!ctx->tag_set)\n                goto err;\n            if (!hw->auth_decrypt(ctx, in, out, len, ctx->buf, ctx->m))\n                goto err;\n            ctx->iv_set = 0;\n            ctx->tag_set = 0;\n            ctx->len_set = 0;\n        }\n    }\n    olen = len;\n    rv = 1;\nerr:\n    *padlen = olen;\n    return rv;\n}', 'static int ccm_tls_cipher(PROV_CCM_CTX *ctx,\n                          unsigned char *out, size_t *padlen,\n                          const unsigned char *in, size_t len)\n{\n    int rv = 0;\n    size_t olen = 0;\n    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)ctx->m))\n        goto err;\n    if (ctx->enc)\n        memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN);\n    memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN);\n    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;\n    if (!ccm_set_iv(ctx, len))\n        goto err;\n    if (!ctx->hw->setaad(ctx, ctx->buf, ctx->tls_aad_len))\n        goto err;\n    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;\n    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;\n    if (ctx->enc) {\n        if (!ctx->hw->auth_encrypt(ctx, in, out, len,  out + len, ctx->m))\n            goto err;\n        olen = len + EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m;\n    } else {\n        if (!ctx->hw->auth_decrypt(ctx, in, out, len,\n                                   (unsigned char *)in + len, ctx->m))\n            goto err;\n        olen = len;\n    }\n    rv = 1;\nerr:\n    *padlen = olen;\n    return rv;\n}']