Home | History | Annotate | Line # | Download | only in signature
      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 /* We need to use some engine deprecated APIs */
     11 #define OPENSSL_SUPPRESS_DEPRECATED
     12 
     13 #include <openssl/crypto.h>
     14 #include <openssl/evp.h>
     15 #include <openssl/core_dispatch.h>
     16 #include <openssl/core_names.h>
     17 #include <openssl/params.h>
     18 #include <openssl/err.h>
     19 #include <openssl/proverr.h>
     20 #ifndef FIPS_MODULE
     21 # include <openssl/engine.h>
     22 #endif
     23 #include "prov/implementations.h"
     24 #include "prov/provider_ctx.h"
     25 #include "prov/macsignature.h"
     26 #include "prov/providercommon.h"
     27 
     28 static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx;
     29 static OSSL_FUNC_signature_newctx_fn mac_siphash_newctx;
     30 static OSSL_FUNC_signature_newctx_fn mac_poly1305_newctx;
     31 static OSSL_FUNC_signature_newctx_fn mac_cmac_newctx;
     32 static OSSL_FUNC_signature_digest_sign_init_fn mac_digest_sign_init;
     33 static OSSL_FUNC_signature_digest_sign_update_fn mac_digest_sign_update;
     34 static OSSL_FUNC_signature_digest_sign_final_fn mac_digest_sign_final;
     35 static OSSL_FUNC_signature_freectx_fn mac_freectx;
     36 static OSSL_FUNC_signature_dupctx_fn mac_dupctx;
     37 static OSSL_FUNC_signature_set_ctx_params_fn mac_set_ctx_params;
     38 static OSSL_FUNC_signature_settable_ctx_params_fn mac_hmac_settable_ctx_params;
     39 static OSSL_FUNC_signature_settable_ctx_params_fn mac_siphash_settable_ctx_params;
     40 static OSSL_FUNC_signature_settable_ctx_params_fn mac_poly1305_settable_ctx_params;
     41 static OSSL_FUNC_signature_settable_ctx_params_fn mac_cmac_settable_ctx_params;
     42 
     43 typedef struct {
     44     OSSL_LIB_CTX *libctx;
     45     char *propq;
     46     MAC_KEY *key;
     47     EVP_MAC_CTX *macctx;
     48 } PROV_MAC_CTX;
     49 
     50 static void *mac_newctx(void *provctx, const char *propq, const char *macname)
     51 {
     52     PROV_MAC_CTX *pmacctx;
     53     EVP_MAC *mac = NULL;
     54 
     55     if (!ossl_prov_is_running())
     56         return NULL;
     57 
     58     pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX));
     59     if (pmacctx == NULL)
     60         return NULL;
     61 
     62     pmacctx->libctx = PROV_LIBCTX_OF(provctx);
     63     if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) {
     64         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
     65         goto err;
     66     }
     67 
     68     mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq);
     69     if (mac == NULL)
     70         goto err;
     71 
     72     pmacctx->macctx = EVP_MAC_CTX_new(mac);
     73     if (pmacctx->macctx == NULL)
     74         goto err;
     75 
     76     EVP_MAC_free(mac);
     77 
     78     return pmacctx;
     79 
     80  err:
     81     OPENSSL_free(pmacctx->propq);
     82     OPENSSL_free(pmacctx);
     83     EVP_MAC_free(mac);
     84     return NULL;
     85 }
     86 
     87 #define MAC_NEWCTX(funcname, macname) \
     88     static void *mac_##funcname##_newctx(void *provctx, const char *propq) \
     89     { \
     90         return mac_newctx(provctx, propq, macname); \
     91     }
     92 
     93 MAC_NEWCTX(hmac, "HMAC")
     94 MAC_NEWCTX(siphash, "SIPHASH")
     95 MAC_NEWCTX(poly1305, "POLY1305")
     96 MAC_NEWCTX(cmac, "CMAC")
     97 
     98 static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
     99                                 const OSSL_PARAM params[])
    100 {
    101     PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
    102     const char *ciphername = NULL, *engine = NULL;
    103 
    104     if (!ossl_prov_is_running()
    105         || pmacctx == NULL)
    106         return 0;
    107 
    108     if (pmacctx->key == NULL && vkey == NULL) {
    109         ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
    110         return 0;
    111     }
    112 
    113     if (vkey != NULL) {
    114         if (!ossl_mac_key_up_ref(vkey))
    115             return 0;
    116         ossl_mac_key_free(pmacctx->key);
    117         pmacctx->key = vkey;
    118     }
    119 
    120     if (pmacctx->key->cipher.cipher != NULL)
    121         ciphername = (char *)EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher);
    122 #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
    123     if (pmacctx->key->cipher.engine != NULL)
    124         engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine);
    125 #endif
    126 
    127     if (!ossl_prov_set_macctx(pmacctx->macctx, NULL,
    128                               (char *)ciphername,
    129                               (char *)mdname,
    130                               (char *)engine,
    131                               pmacctx->key->properties,
    132                               NULL, 0))
    133         return 0;
    134 
    135     if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key,
    136                       pmacctx->key->priv_key_len, params))
    137         return 0;
    138 
    139     return 1;
    140 }
    141 
    142 int mac_digest_sign_update(void *vpmacctx, const unsigned char *data,
    143                            size_t datalen)
    144 {
    145     PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
    146 
    147     if (pmacctx == NULL || pmacctx->macctx == NULL)
    148         return 0;
    149 
    150     return EVP_MAC_update(pmacctx->macctx, data, datalen);
    151 }
    152 
    153 int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen,
    154                           size_t macsize)
    155 {
    156     PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
    157 
    158     if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL)
    159         return 0;
    160 
    161     return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize);
    162 }
    163 
    164 static void mac_freectx(void *vpmacctx)
    165 {
    166     PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
    167 
    168     OPENSSL_free(ctx->propq);
    169     EVP_MAC_CTX_free(ctx->macctx);
    170     ossl_mac_key_free(ctx->key);
    171     OPENSSL_free(ctx);
    172 }
    173 
    174 static void *mac_dupctx(void *vpmacctx)
    175 {
    176     PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx;
    177     PROV_MAC_CTX *dstctx;
    178 
    179     if (!ossl_prov_is_running())
    180         return NULL;
    181 
    182     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
    183     if (dstctx == NULL)
    184         return NULL;
    185 
    186     *dstctx = *srcctx;
    187     dstctx->propq = NULL;
    188     dstctx->key = NULL;
    189     dstctx->macctx = NULL;
    190 
    191     if (srcctx->propq != NULL && (dstctx->propq = OPENSSL_strdup(srcctx->propq)) == NULL)
    192         goto err;
    193 
    194     if (srcctx->key != NULL && !ossl_mac_key_up_ref(srcctx->key))
    195         goto err;
    196     dstctx->key = srcctx->key;
    197 
    198     if (srcctx->macctx != NULL) {
    199         dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx);
    200         if (dstctx->macctx == NULL)
    201             goto err;
    202     }
    203 
    204     return dstctx;
    205  err:
    206     mac_freectx(dstctx);
    207     return NULL;
    208 }
    209 
    210 static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[])
    211 {
    212     PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
    213 
    214     return EVP_MAC_CTX_set_params(ctx->macctx, params);
    215 }
    216 
    217 static const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx,
    218                                                  void *provctx,
    219                                                  const char *macname)
    220 {
    221     EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname,
    222                                  NULL);
    223     const OSSL_PARAM *params;
    224 
    225     if (mac == NULL)
    226         return NULL;
    227 
    228     params = EVP_MAC_settable_ctx_params(mac);
    229     EVP_MAC_free(mac);
    230 
    231     return params;
    232 }
    233 
    234 #define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \
    235     static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \
    236                                                                   void *provctx) \
    237     { \
    238         return mac_settable_ctx_params(ctx, provctx, macname); \
    239     }
    240 
    241 MAC_SETTABLE_CTX_PARAMS(hmac, "HMAC")
    242 MAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH")
    243 MAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305")
    244 MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC")
    245 
    246 #define MAC_SIGNATURE_FUNCTIONS(funcname) \
    247     const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = { \
    248         { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \
    249         { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \
    250         (void (*)(void))mac_digest_sign_init }, \
    251         { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \
    252         (void (*)(void))mac_digest_sign_update }, \
    253         { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, \
    254         (void (*)(void))mac_digest_sign_final }, \
    255         { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx }, \
    256         { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx }, \
    257         { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \
    258           (void (*)(void))mac_set_ctx_params }, \
    259         { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
    260           (void (*)(void))mac_##funcname##_settable_ctx_params }, \
    261         { 0, NULL } \
    262     };
    263 
    264 MAC_SIGNATURE_FUNCTIONS(hmac)
    265 MAC_SIGNATURE_FUNCTIONS(siphash)
    266 MAC_SIGNATURE_FUNCTIONS(poly1305)
    267 MAC_SIGNATURE_FUNCTIONS(cmac)
    268