Home | History | Annotate | Line # | Download | only in ciphers
      1 /*
      2  * Copyright 2019-2024 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 /* Dispatch functions for RC4_HMAC_MD5 cipher */
     11 
     12 /*
     13  * MD5 and RC4 low level APIs are deprecated for public use, but still ok for
     14  * internal use.
     15  */
     16 #include "internal/deprecated.h"
     17 
     18 #include <openssl/proverr.h>
     19 #include "cipher_rc4_hmac_md5.h"
     20 #include "prov/implementations.h"
     21 #include "prov/providercommon.h"
     22 
     23 #define RC4_HMAC_MD5_FLAGS (PROV_CIPHER_FLAG_VARIABLE_LENGTH                   \
     24                             | PROV_CIPHER_FLAG_AEAD)
     25 
     26 #define RC4_HMAC_MD5_KEY_BITS (16 * 8)
     27 #define RC4_HMAC_MD5_BLOCK_BITS (1 * 8)
     28 #define RC4_HMAC_MD5_IV_BITS 0
     29 #define RC4_HMAC_MD5_MODE 0
     30 
     31 #define GET_HW(ctx) ((PROV_CIPHER_HW_RC4_HMAC_MD5 *)ctx->base.hw)
     32 
     33 static OSSL_FUNC_cipher_encrypt_init_fn rc4_hmac_md5_einit;
     34 static OSSL_FUNC_cipher_decrypt_init_fn rc4_hmac_md5_dinit;
     35 static OSSL_FUNC_cipher_newctx_fn rc4_hmac_md5_newctx;
     36 static OSSL_FUNC_cipher_freectx_fn rc4_hmac_md5_freectx;
     37 static OSSL_FUNC_cipher_dupctx_fn rc4_hmac_md5_dupctx;
     38 static OSSL_FUNC_cipher_get_ctx_params_fn rc4_hmac_md5_get_ctx_params;
     39 static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params;
     40 static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params;
     41 static OSSL_FUNC_cipher_settable_ctx_params_fn rc4_hmac_md5_settable_ctx_params;
     42 static OSSL_FUNC_cipher_get_params_fn rc4_hmac_md5_get_params;
     43 #define rc4_hmac_md5_gettable_params ossl_cipher_generic_gettable_params
     44 #define rc4_hmac_md5_update ossl_cipher_generic_stream_update
     45 #define rc4_hmac_md5_final ossl_cipher_generic_stream_final
     46 #define rc4_hmac_md5_cipher ossl_cipher_generic_cipher
     47 
     48 static void *rc4_hmac_md5_newctx(void *provctx)
     49 {
     50     PROV_RC4_HMAC_MD5_CTX *ctx;
     51 
     52     if (!ossl_prov_is_running())
     53         return NULL;
     54 
     55     ctx = OPENSSL_zalloc(sizeof(*ctx));
     56     if (ctx != NULL)
     57         ossl_cipher_generic_initkey(ctx, RC4_HMAC_MD5_KEY_BITS,
     58                                     RC4_HMAC_MD5_BLOCK_BITS,
     59                                     RC4_HMAC_MD5_IV_BITS,
     60                                     RC4_HMAC_MD5_MODE, RC4_HMAC_MD5_FLAGS,
     61                                     ossl_prov_cipher_hw_rc4_hmac_md5(
     62                                         RC4_HMAC_MD5_KEY_BITS
     63                                     ), NULL);
     64      return ctx;
     65 }
     66 
     67 static void rc4_hmac_md5_freectx(void *vctx)
     68 {
     69     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
     70 
     71     ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
     72     OPENSSL_clear_free(ctx,  sizeof(*ctx));
     73 }
     74 
     75 static void *rc4_hmac_md5_dupctx(void *vctx)
     76 {
     77     PROV_RC4_HMAC_MD5_CTX *ctx = vctx;
     78 
     79     if (ctx == NULL)
     80         return NULL;
     81     return OPENSSL_memdup(ctx, sizeof(*ctx));
     82 }
     83 
     84 static int rc4_hmac_md5_einit(void *ctx, const unsigned char *key,
     85                               size_t keylen, const unsigned char *iv,
     86                               size_t ivlen, const OSSL_PARAM params[])
     87 {
     88     if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL))
     89         return 0;
     90     return rc4_hmac_md5_set_ctx_params(ctx, params);
     91 }
     92 
     93 static int rc4_hmac_md5_dinit(void *ctx, const unsigned char *key,
     94                               size_t keylen, const unsigned char *iv,
     95                               size_t ivlen, const OSSL_PARAM params[])
     96 {
     97     if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL))
     98         return 0;
     99     return rc4_hmac_md5_set_ctx_params(ctx, params);
    100 }
    101 
    102 static const OSSL_PARAM rc4_hmac_md5_known_gettable_ctx_params[] = {
    103     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
    104     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
    105     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
    106     OSSL_PARAM_END
    107 };
    108 const OSSL_PARAM *rc4_hmac_md5_gettable_ctx_params(ossl_unused void *cctx,
    109                                                    ossl_unused void *provctx)
    110 {
    111     return rc4_hmac_md5_known_gettable_ctx_params;
    112 }
    113 
    114 static int rc4_hmac_md5_get_ctx_params(void *vctx, OSSL_PARAM params[])
    115 {
    116     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
    117     OSSL_PARAM *p;
    118 
    119     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
    120     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) {
    121         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    122         return 0;
    123     }
    124 
    125     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
    126     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) {
    127         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    128         return 0;
    129     }
    130     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
    131     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) {
    132         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
    133         return 0;
    134     }
    135     return 1;
    136 }
    137 
    138 static const OSSL_PARAM rc4_hmac_md5_known_settable_ctx_params[] = {
    139     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
    140     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
    141     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
    142     OSSL_PARAM_END
    143 };
    144 const OSSL_PARAM *rc4_hmac_md5_settable_ctx_params(ossl_unused void *cctx,
    145                                                    ossl_unused void *provctx)
    146 {
    147     return rc4_hmac_md5_known_settable_ctx_params;
    148 }
    149 
    150 static int rc4_hmac_md5_set_ctx_params(void *vctx, const OSSL_PARAM params[])
    151 {
    152     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
    153     const OSSL_PARAM *p;
    154     size_t sz;
    155 
    156     if (params == NULL)
    157         return 1;
    158 
    159     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
    160     if (p != NULL) {
    161         if (!OSSL_PARAM_get_size_t(p, &sz)) {
    162             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
    163             return 0;
    164         }
    165         if (ctx->base.keylen != sz) {
    166             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
    167             return 0;
    168         }
    169     }
    170 
    171     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
    172     if (p != NULL) {
    173         if (!OSSL_PARAM_get_size_t(p, &sz)) {
    174             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
    175             return 0;
    176         }
    177         if (ctx->base.ivlen != sz) {
    178             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
    179             return 0;
    180         }
    181     }
    182 
    183     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
    184     if (p != NULL) {
    185         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
    186             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
    187             return 0;
    188         }
    189         sz = GET_HW(ctx)->tls_init(&ctx->base, p->data, p->data_size);
    190         if (sz == 0) {
    191             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);
    192             return 0;
    193         }
    194         ctx->tls_aad_pad_sz = sz;
    195     }
    196     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_MAC_KEY);
    197     if (p != NULL) {
    198         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
    199             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
    200             return 0;
    201         }
    202         GET_HW(ctx)->init_mackey(&ctx->base, p->data, p->data_size);
    203     }
    204     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
    205     if (p != NULL) {
    206         if (!OSSL_PARAM_get_uint(p, &ctx->base.tlsversion)) {
    207             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
    208             return 0;
    209         }
    210     }
    211 
    212     return 1;
    213 }
    214 
    215 static int rc4_hmac_md5_get_params(OSSL_PARAM params[])
    216 {
    217     return ossl_cipher_generic_get_params(params, RC4_HMAC_MD5_MODE,
    218                                           RC4_HMAC_MD5_FLAGS,
    219                                           RC4_HMAC_MD5_KEY_BITS,
    220                                           RC4_HMAC_MD5_BLOCK_BITS,
    221                                           RC4_HMAC_MD5_IV_BITS);
    222 }
    223 
    224 const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = {
    225     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))rc4_hmac_md5_newctx },
    226     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))rc4_hmac_md5_freectx },
    227     { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))rc4_hmac_md5_dupctx },
    228     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc4_hmac_md5_einit },
    229     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc4_hmac_md5_dinit },
    230     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))rc4_hmac_md5_update },
    231     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))rc4_hmac_md5_final },
    232     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))rc4_hmac_md5_cipher },
    233     { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))rc4_hmac_md5_get_params },
    234     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
    235         (void (*)(void))rc4_hmac_md5_gettable_params },
    236     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,
    237         (void (*)(void))rc4_hmac_md5_get_ctx_params },
    238     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
    239         (void (*)(void))rc4_hmac_md5_gettable_ctx_params },
    240     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,
    241         (void (*)(void))rc4_hmac_md5_set_ctx_params },
    242     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
    243         (void (*)(void))rc4_hmac_md5_settable_ctx_params },
    244     { 0, NULL }
    245 };
    246