Home | History | Annotate | Line # | Download | only in digests
      1 /*
      2  * Copyright 2019-2023 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 <openssl/crypto.h>
     11 #include <openssl/core_names.h>
     12 #include <openssl/proverr.h>
     13 #include <openssl/err.h>
     14 #include "prov/blake2.h"
     15 #include "prov/digestcommon.h"
     16 #include "prov/implementations.h"
     17 
     18 #define IMPLEMENT_BLAKE_functions(variant, VARIANT, variantsize)                                                  \
     19     static const OSSL_PARAM known_blake##variant##_ctx_params[] = {                                               \
     20         { OSSL_DIGEST_PARAM_SIZE, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0 },                                      \
     21         OSSL_PARAM_END                                                                                            \
     22     };                                                                                                            \
     23                                                                                                                   \
     24     const OSSL_PARAM *ossl_blake##variant##_gettable_ctx_params(ossl_unused void *ctx,                            \
     25         ossl_unused void *pctx)                                                                                   \
     26     {                                                                                                             \
     27         return known_blake##variant##_ctx_params;                                                                 \
     28     }                                                                                                             \
     29                                                                                                                   \
     30     const OSSL_PARAM *ossl_blake##variant##_settable_ctx_params(ossl_unused void *ctx,                            \
     31         ossl_unused void *pctx)                                                                                   \
     32     {                                                                                                             \
     33         return known_blake##variant##_ctx_params;                                                                 \
     34     }                                                                                                             \
     35                                                                                                                   \
     36     int ossl_blake##variant##_get_ctx_params(void *vctx, OSSL_PARAM params[])                                     \
     37     {                                                                                                             \
     38         struct blake##variant##_md_data_st *mdctx = vctx;                                                         \
     39         OSSL_PARAM *p;                                                                                            \
     40                                                                                                                   \
     41         BLAKE##VARIANT##_CTX *ctx = &mdctx->ctx;                                                                  \
     42                                                                                                                   \
     43         if (ctx == NULL)                                                                                          \
     44             return 0;                                                                                             \
     45         if (ossl_param_is_empty(params))                                                                          \
     46             return 1;                                                                                             \
     47                                                                                                                   \
     48         p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE);                                                    \
     49         if (p != NULL                                                                                             \
     50             && !OSSL_PARAM_set_uint(p, (unsigned int)mdctx->params.digest_length)) {                              \
     51             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);                                              \
     52             return 0;                                                                                             \
     53         }                                                                                                         \
     54                                                                                                                   \
     55         return 1;                                                                                                 \
     56     }                                                                                                             \
     57                                                                                                                   \
     58     int ossl_blake##variant##_set_ctx_params(void *vctx, const OSSL_PARAM params[])                               \
     59     {                                                                                                             \
     60         size_t size;                                                                                              \
     61         struct blake##variant##_md_data_st *mdctx = vctx;                                                         \
     62         const OSSL_PARAM *p;                                                                                      \
     63                                                                                                                   \
     64         BLAKE##VARIANT##_CTX *ctx = &mdctx->ctx;                                                                  \
     65                                                                                                                   \
     66         if (ctx == NULL)                                                                                          \
     67             return 0;                                                                                             \
     68         if (ossl_param_is_empty(params))                                                                          \
     69             return 1;                                                                                             \
     70                                                                                                                   \
     71         p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_SIZE);                                              \
     72         if (p != NULL) {                                                                                          \
     73             if (!OSSL_PARAM_get_size_t(p, &size)) {                                                               \
     74                 ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);                                          \
     75                 return 0;                                                                                         \
     76             }                                                                                                     \
     77             if (size < 1 || size > BLAKE##VARIANT##_OUTBYTES) {                                                   \
     78                 ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);                                              \
     79                 return 0;                                                                                         \
     80             }                                                                                                     \
     81             ossl_blake##variant##_param_set_digest_length(&mdctx->params, (uint8_t)size);                         \
     82         }                                                                                                         \
     83                                                                                                                   \
     84         return 1;                                                                                                 \
     85     }                                                                                                             \
     86                                                                                                                   \
     87     static int ossl_blake##variantsize##_init(void *ctx)                                                          \
     88     {                                                                                                             \
     89         struct blake##variant##_md_data_st *mdctx = ctx;                                                          \
     90         uint8_t digest_length = mdctx->params.digest_length;                                                      \
     91                                                                                                                   \
     92         ossl_blake##variant##_param_init(&mdctx->params);                                                         \
     93         if (digest_length != 0)                                                                                   \
     94             mdctx->params.digest_length = digest_length;                                                          \
     95         return ossl_blake##variant##_init(&mdctx->ctx, &mdctx->params);                                           \
     96     }                                                                                                             \
     97                                                                                                                   \
     98     static OSSL_FUNC_digest_init_fn blake##variantsize##_internal_init;                                           \
     99     static OSSL_FUNC_digest_newctx_fn blake##variantsize##_newctx;                                                \
    100     static OSSL_FUNC_digest_freectx_fn blake##variantsize##_freectx;                                              \
    101     static OSSL_FUNC_digest_dupctx_fn blake##variantsize##_dupctx;                                                \
    102     static OSSL_FUNC_digest_final_fn blake##variantsize##_internal_final;                                         \
    103     static OSSL_FUNC_digest_get_params_fn blake##variantsize##_get_params;                                        \
    104                                                                                                                   \
    105     static int blake##variantsize##_internal_init(void *ctx, const OSSL_PARAM params[])                           \
    106     {                                                                                                             \
    107         return ossl_prov_is_running() && ossl_blake##variant##_set_ctx_params(ctx, params)                        \
    108             && ossl_blake##variantsize##_init(ctx);                                                               \
    109     }                                                                                                             \
    110                                                                                                                   \
    111     static void *blake##variantsize##_newctx(void *prov_ctx)                                                      \
    112     {                                                                                                             \
    113         struct blake##variant##_md_data_st *ctx;                                                                  \
    114                                                                                                                   \
    115         ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL;                                       \
    116         return ctx;                                                                                               \
    117     }                                                                                                             \
    118                                                                                                                   \
    119     static void blake##variantsize##_freectx(void *vctx)                                                          \
    120     {                                                                                                             \
    121         struct blake##variant##_md_data_st *ctx;                                                                  \
    122                                                                                                                   \
    123         ctx = (struct blake##variant##_md_data_st *)vctx;                                                         \
    124         OPENSSL_clear_free(ctx, sizeof(*ctx));                                                                    \
    125     }                                                                                                             \
    126                                                                                                                   \
    127     static void *blake##variantsize##_dupctx(void *ctx)                                                           \
    128     {                                                                                                             \
    129         struct blake##variant##_md_data_st *in, *ret;                                                             \
    130                                                                                                                   \
    131         in = (struct blake##variant##_md_data_st *)ctx;                                                           \
    132         ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) : NULL;                                       \
    133         if (ret != NULL)                                                                                          \
    134             *ret = *in;                                                                                           \
    135         return ret;                                                                                               \
    136     }                                                                                                             \
    137                                                                                                                   \
    138     static void blake##variantsize##_copyctx(void *voutctx, void *vinctx)                                         \
    139     {                                                                                                             \
    140         struct blake##variant##_md_data_st *inctx, *outctx;                                                       \
    141                                                                                                                   \
    142         outctx = (struct blake##variant##_md_data_st *)voutctx;                                                   \
    143         inctx = (struct blake##variant##_md_data_st *)vinctx;                                                     \
    144         *outctx = *inctx;                                                                                         \
    145     }                                                                                                             \
    146                                                                                                                   \
    147     static int blake##variantsize##_internal_final(void *ctx, unsigned char *out,                                 \
    148         size_t *outl, size_t outsz)                                                                               \
    149     {                                                                                                             \
    150         struct blake##variant##_md_data_st *b_ctx;                                                                \
    151                                                                                                                   \
    152         b_ctx = (struct blake##variant##_md_data_st *)ctx;                                                        \
    153                                                                                                                   \
    154         if (!ossl_prov_is_running())                                                                              \
    155             return 0;                                                                                             \
    156                                                                                                                   \
    157         *outl = b_ctx->ctx.outlen;                                                                                \
    158                                                                                                                   \
    159         if (outsz == 0)                                                                                           \
    160             return 1;                                                                                             \
    161                                                                                                                   \
    162         if (outsz < *outl) {                                                                                      \
    163             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE);                                                  \
    164             return 0;                                                                                             \
    165         }                                                                                                         \
    166                                                                                                                   \
    167         return ossl_blake##variant##_final(out, ctx);                                                             \
    168     }                                                                                                             \
    169                                                                                                                   \
    170     static int blake##variantsize##_get_params(OSSL_PARAM params[])                                               \
    171     {                                                                                                             \
    172         return ossl_digest_default_get_params(params, BLAKE##VARIANT##_BLOCKBYTES, BLAKE##VARIANT##_OUTBYTES, 0); \
    173     }                                                                                                             \
    174                                                                                                                   \
    175     const OSSL_DISPATCH ossl_blake##variantsize##_functions[] = {                                                 \
    176         { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))blake##variantsize##_newctx },                                 \
    177         { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))ossl_blake##variant##_update },                                \
    178         { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))blake##variantsize##_internal_final },                          \
    179         { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))blake##variantsize##_freectx },                               \
    180         { OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))blake##variantsize##_dupctx },                                 \
    181         { OSSL_FUNC_DIGEST_COPYCTX, (void (*)(void))blake##variantsize##_copyctx },                               \
    182         { OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))blake##variantsize##_get_params },                         \
    183         { OSSL_FUNC_DIGEST_GETTABLE_PARAMS,                                                                       \
    184             (void (*)(void))ossl_digest_default_gettable_params },                                                \
    185         { OSSL_FUNC_DIGEST_INIT, (void (*)(void))blake##variantsize##_internal_init },                            \
    186         { OSSL_FUNC_DIGEST_GETTABLE_CTX_PARAMS,                                                                   \
    187             (void (*)(void))ossl_blake##variant##_gettable_ctx_params },                                          \
    188         { OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS,                                                                   \
    189             (void (*)(void))ossl_blake##variant##_settable_ctx_params },                                          \
    190         { OSSL_FUNC_DIGEST_GET_CTX_PARAMS,                                                                        \
    191             (void (*)(void))ossl_blake##variant##_get_ctx_params },                                               \
    192         { OSSL_FUNC_DIGEST_SET_CTX_PARAMS,                                                                        \
    193             (void (*)(void))ossl_blake##variant##_set_ctx_params },                                               \
    194         { 0, NULL }                                                                                               \
    195     };
    196 
    197 IMPLEMENT_BLAKE_functions(2s, 2S, 2s256)
    198 IMPLEMENT_BLAKE_functions(2b, 2B, 2b512)
    199