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 33static OSSL_FUNC_cipher_encrypt_init_fn rc4_hmac_md5_einit; 34static OSSL_FUNC_cipher_decrypt_init_fn rc4_hmac_md5_dinit; 35static OSSL_FUNC_cipher_newctx_fn rc4_hmac_md5_newctx; 36static OSSL_FUNC_cipher_freectx_fn rc4_hmac_md5_freectx; 37static OSSL_FUNC_cipher_dupctx_fn rc4_hmac_md5_dupctx; 38static OSSL_FUNC_cipher_get_ctx_params_fn rc4_hmac_md5_get_ctx_params; 39static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params; 40static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params; 41static OSSL_FUNC_cipher_settable_ctx_params_fn rc4_hmac_md5_settable_ctx_params; 42static 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 48static 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 67static 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 75static 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 84static 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 93static 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 102static 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}; 108const 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 114static 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 138static 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}; 144const 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 150static 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 215static 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 224const 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