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