b757197110d73a0b725330a7d7a16d7df487ecb3
[openssl.git] / providers / implementations / ciphers / cipher_rc4_hmac_md5.c
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 /* 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 "cipher_rc4_hmac_md5.h"
19 #include "prov/implementations.h"
20 #include "prov/providercommon.h"
21 #include "prov/providercommonerr.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_newctx_fn rc4_hmac_md5_newctx;
34 static OSSL_FUNC_cipher_freectx_fn rc4_hmac_md5_freectx;
35 static OSSL_FUNC_cipher_get_ctx_params_fn rc4_hmac_md5_get_ctx_params;
36 static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params;
37 static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params;
38 static OSSL_FUNC_cipher_settable_ctx_params_fn rc4_hmac_md5_settable_ctx_params;
39 static OSSL_FUNC_cipher_get_params_fn rc4_hmac_md5_get_params;
40 #define rc4_hmac_md5_gettable_params ossl_cipher_generic_gettable_params
41 #define rc4_hmac_md5_einit ossl_cipher_generic_einit
42 #define rc4_hmac_md5_dinit ossl_cipher_generic_dinit
43 #define rc4_hmac_md5_update ossl_cipher_generic_stream_update
44 #define rc4_hmac_md5_final ossl_cipher_generic_stream_final
45 #define rc4_hmac_md5_cipher ossl_cipher_generic_cipher
46
47 static void *rc4_hmac_md5_newctx(void *provctx)
48 {
49     PROV_RC4_HMAC_MD5_CTX *ctx;
50
51     if (!ossl_prov_is_running())
52         return NULL;
53
54     ctx = OPENSSL_zalloc(sizeof(*ctx));
55     if (ctx != NULL)
56         ossl_cipher_generic_initkey(ctx, RC4_HMAC_MD5_KEY_BITS,
57                                     RC4_HMAC_MD5_BLOCK_BITS,
58                                     RC4_HMAC_MD5_IV_BITS,
59                                     RC4_HMAC_MD5_MODE, RC4_HMAC_MD5_FLAGS,
60                                     ossl_prov_cipher_hw_rc4_hmac_md5(
61                                         RC4_HMAC_MD5_KEY_BITS
62                                     ), NULL);
63      return ctx;
64 }
65
66 static void rc4_hmac_md5_freectx(void *vctx)
67 {
68     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
69
70     ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
71     OPENSSL_clear_free(ctx,  sizeof(*ctx));
72 }
73
74 static const OSSL_PARAM rc4_hmac_md5_known_gettable_ctx_params[] = {
75     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
76     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
77     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL),
78     OSSL_PARAM_END
79 };
80 const OSSL_PARAM *rc4_hmac_md5_gettable_ctx_params(ossl_unused void *provctx)
81 {
82     return rc4_hmac_md5_known_gettable_ctx_params;
83 }
84
85 static int rc4_hmac_md5_get_ctx_params(void *vctx, OSSL_PARAM params[])
86 {
87     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
88     OSSL_PARAM *p;
89
90     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
91     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.keylen)) {
92         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
93         return 0;
94     }
95
96     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN);
97     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->base.ivlen)) {
98         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
99         return 0;
100     }
101     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD);
102     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) {
103         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
104         return 0;
105     }
106     return 1;
107 }
108
109 static const OSSL_PARAM rc4_hmac_md5_known_settable_ctx_params[] = {
110     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
111     OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),
112     OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0),
113     OSSL_PARAM_END
114 };
115 const OSSL_PARAM *rc4_hmac_md5_settable_ctx_params(ossl_unused void *provctx)
116 {
117     return rc4_hmac_md5_known_settable_ctx_params;
118 }
119
120 static int rc4_hmac_md5_set_ctx_params(void *vctx, const OSSL_PARAM params[])
121 {
122     PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx;
123     const OSSL_PARAM *p;
124     size_t sz;
125
126     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
127     if (p != NULL) {
128         if (!OSSL_PARAM_get_size_t(p, &sz)) {
129             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
130             return 0;
131         }
132         if (ctx->base.keylen != sz) {
133             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
134             return 0;
135         }
136     }
137
138     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_IVLEN);
139     if (p != NULL) {
140         if (!OSSL_PARAM_get_size_t(p, &sz)) {
141             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
142             return 0;
143         }
144         if (ctx->base.ivlen != sz) {
145             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH);
146             return 0;
147         }
148     }
149
150     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
151     if (p != NULL) {
152         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
153             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
154             return 0;
155         }
156         sz = GET_HW(ctx)->tls_init(&ctx->base, p->data, p->data_size);
157         if (sz == 0) {
158             ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA);
159             return 0;
160         }
161         ctx->tls_aad_pad_sz = sz;
162     }
163     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD);
164     if (p != NULL) {
165         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
166             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
167             return 0;
168         }
169         GET_HW(ctx)->init_mackey(&ctx->base, p->data, p->data_size);
170     }
171     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION);
172     if (p != NULL) {
173         if (!OSSL_PARAM_get_uint(p, &ctx->base.tlsversion)) {
174             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
175             return 0;
176         }
177     }
178
179     return 1;
180 }
181
182 static int rc4_hmac_md5_get_params(OSSL_PARAM params[])
183 {
184     return ossl_cipher_generic_get_params(params, RC4_HMAC_MD5_MODE,
185                                           RC4_HMAC_MD5_FLAGS,
186                                           RC4_HMAC_MD5_KEY_BITS,
187                                           RC4_HMAC_MD5_BLOCK_BITS,
188                                           RC4_HMAC_MD5_IV_BITS);
189 }
190
191 const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = {
192     { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))rc4_hmac_md5_newctx },
193     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))rc4_hmac_md5_freectx },
194     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc4_hmac_md5_einit },
195     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc4_hmac_md5_dinit },
196     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))rc4_hmac_md5_update },
197     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))rc4_hmac_md5_final },
198     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))rc4_hmac_md5_cipher },
199     { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))rc4_hmac_md5_get_params },
200     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,
201         (void (*)(void))rc4_hmac_md5_gettable_params },
202     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,
203         (void (*)(void))rc4_hmac_md5_get_ctx_params },
204     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,
205         (void (*)(void))rc4_hmac_md5_gettable_ctx_params },
206     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,
207         (void (*)(void))rc4_hmac_md5_set_ctx_params },
208     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,
209         (void (*)(void))rc4_hmac_md5_settable_ctx_params },
210     { 0, NULL }
211 };