1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/* Dispatch functions for RC5 cipher modes ecb, cbc, ofb, cfb */
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci/*
13e1051a39Sopenharmony_ci * RC5 low level APIs are deprecated for public use, but still ok for internal
14e1051a39Sopenharmony_ci * use.
15e1051a39Sopenharmony_ci */
16e1051a39Sopenharmony_ci#include "internal/deprecated.h"
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_ci#include <openssl/proverr.h>
19e1051a39Sopenharmony_ci#include "cipher_rc5.h"
20e1051a39Sopenharmony_ci#include "prov/implementations.h"
21e1051a39Sopenharmony_ci#include "prov/providercommon.h"
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ci#define RC5_FLAGS PROV_CIPHER_FLAG_VARIABLE_LENGTH
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_encrypt_init_fn rc5_einit;
26e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_decrypt_init_fn rc5_dinit;
27e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_freectx_fn rc5_freectx;
28e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_dupctx_fn rc5_dupctx;
29e1051a39Sopenharmony_ciOSSL_FUNC_cipher_gettable_ctx_params_fn rc5_gettable_ctx_params;
30e1051a39Sopenharmony_ciOSSL_FUNC_cipher_settable_ctx_params_fn rc5_settable_ctx_params;
31e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_set_ctx_params_fn rc5_set_ctx_params;
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_cistatic void rc5_freectx(void *vctx)
34e1051a39Sopenharmony_ci{
35e1051a39Sopenharmony_ci    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
36e1051a39Sopenharmony_ci
37e1051a39Sopenharmony_ci    ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
38e1051a39Sopenharmony_ci    OPENSSL_clear_free(ctx,  sizeof(*ctx));
39e1051a39Sopenharmony_ci}
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_cistatic void *rc5_dupctx(void *ctx)
42e1051a39Sopenharmony_ci{
43e1051a39Sopenharmony_ci    PROV_RC5_CTX *in = (PROV_RC5_CTX *)ctx;
44e1051a39Sopenharmony_ci    PROV_RC5_CTX *ret;
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci    if (!ossl_prov_is_running())
47e1051a39Sopenharmony_ci        return NULL;
48e1051a39Sopenharmony_ci
49e1051a39Sopenharmony_ci    ret = OPENSSL_malloc(sizeof(*ret));
50e1051a39Sopenharmony_ci    if (ret == NULL) {
51e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
52e1051a39Sopenharmony_ci        return NULL;
53e1051a39Sopenharmony_ci    }
54e1051a39Sopenharmony_ci    *ret = *in;
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_ci    return ret;
57e1051a39Sopenharmony_ci}
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_cistatic int rc5_einit(void *ctx, const unsigned char *key, size_t keylen,
60e1051a39Sopenharmony_ci                          const unsigned char *iv, size_t ivlen,
61e1051a39Sopenharmony_ci                          const OSSL_PARAM params[])
62e1051a39Sopenharmony_ci{
63e1051a39Sopenharmony_ci    if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL))
64e1051a39Sopenharmony_ci        return 0;
65e1051a39Sopenharmony_ci    return rc5_set_ctx_params(ctx, params);
66e1051a39Sopenharmony_ci}
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_cistatic int rc5_dinit(void *ctx, const unsigned char *key, size_t keylen,
69e1051a39Sopenharmony_ci                          const unsigned char *iv, size_t ivlen,
70e1051a39Sopenharmony_ci                          const OSSL_PARAM params[])
71e1051a39Sopenharmony_ci{
72e1051a39Sopenharmony_ci    if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL))
73e1051a39Sopenharmony_ci        return 0;
74e1051a39Sopenharmony_ci    return rc5_set_ctx_params(ctx, params);
75e1051a39Sopenharmony_ci}
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_cistatic int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[])
78e1051a39Sopenharmony_ci{
79e1051a39Sopenharmony_ci    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
80e1051a39Sopenharmony_ci    const OSSL_PARAM *p;
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci    if (params == NULL)
83e1051a39Sopenharmony_ci        return 1;
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ci    if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params))
86e1051a39Sopenharmony_ci        return 0;
87e1051a39Sopenharmony_ci
88e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS);
89e1051a39Sopenharmony_ci    if (p != NULL) {
90e1051a39Sopenharmony_ci        unsigned int rounds;
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ci        if (!OSSL_PARAM_get_uint(p, &rounds)) {
93e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
94e1051a39Sopenharmony_ci            return 0;
95e1051a39Sopenharmony_ci        }
96e1051a39Sopenharmony_ci        if (rounds != RC5_8_ROUNDS
97e1051a39Sopenharmony_ci            && rounds != RC5_12_ROUNDS
98e1051a39Sopenharmony_ci            && rounds != RC5_16_ROUNDS) {
99e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
100e1051a39Sopenharmony_ci            return 0;
101e1051a39Sopenharmony_ci        }
102e1051a39Sopenharmony_ci        ctx->rounds = rounds;
103e1051a39Sopenharmony_ci    }
104e1051a39Sopenharmony_ci    return 1;
105e1051a39Sopenharmony_ci}
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ciCIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc5)
108e1051a39Sopenharmony_ci    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
109e1051a39Sopenharmony_ciCIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc5)
110e1051a39Sopenharmony_ci
111e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc5)
112e1051a39Sopenharmony_ci    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
113e1051a39Sopenharmony_ci    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
114e1051a39Sopenharmony_ciCIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc5)
115e1051a39Sopenharmony_ci
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_cistatic int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[])
118e1051a39Sopenharmony_ci{
119e1051a39Sopenharmony_ci    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
120e1051a39Sopenharmony_ci    OSSL_PARAM *p;
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ci    if (!ossl_cipher_generic_get_ctx_params(vctx, params))
123e1051a39Sopenharmony_ci        return 0;
124e1051a39Sopenharmony_ci    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ROUNDS);
125e1051a39Sopenharmony_ci    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->rounds)) {
126e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
127e1051a39Sopenharmony_ci        return 0;
128e1051a39Sopenharmony_ci    }
129e1051a39Sopenharmony_ci    return 1;
130e1051a39Sopenharmony_ci}
131e1051a39Sopenharmony_ci
132e1051a39Sopenharmony_ci#define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,             \
133e1051a39Sopenharmony_ci                         blkbits, ivbits, typ)                                 \
134e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;   \
135e1051a39Sopenharmony_cistatic int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])          \
136e1051a39Sopenharmony_ci{                                                                              \
137e1051a39Sopenharmony_ci    return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,    \
138e1051a39Sopenharmony_ci                                          flags, kbits, blkbits, ivbits);      \
139e1051a39Sopenharmony_ci}                                                                              \
140e1051a39Sopenharmony_cistatic OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;           \
141e1051a39Sopenharmony_cistatic void * alg##_##kbits##_##lcmode##_newctx(void *provctx)                 \
142e1051a39Sopenharmony_ci{                                                                              \
143e1051a39Sopenharmony_ci     PROV_##UCALG##_CTX *ctx;                                                  \
144e1051a39Sopenharmony_ci     if (!ossl_prov_is_running())                                              \
145e1051a39Sopenharmony_ci        return NULL;                                                           \
146e1051a39Sopenharmony_ci     ctx = OPENSSL_zalloc(sizeof(*ctx));                                       \
147e1051a39Sopenharmony_ci     if (ctx != NULL) {                                                        \
148e1051a39Sopenharmony_ci         ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits,              \
149e1051a39Sopenharmony_ci                                     EVP_CIPH_##UCMODE##_MODE, flags,          \
150e1051a39Sopenharmony_ci                                     ossl_prov_cipher_hw_##alg##_##lcmode(kbits),\
151e1051a39Sopenharmony_ci                                NULL);                                         \
152e1051a39Sopenharmony_ci         ctx->rounds = RC5_12_ROUNDS;                                          \
153e1051a39Sopenharmony_ci     }                                                                         \
154e1051a39Sopenharmony_ci     return ctx;                                                               \
155e1051a39Sopenharmony_ci}                                                                              \
156e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = {                \
157e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
158e1051a39Sopenharmony_ci      (void (*)(void)) alg##_##kbits##_##lcmode##_newctx },                    \
159e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx },              \
160e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx },                \
161e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc5_einit },              \
162e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc5_dinit },              \
163e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\
164e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final },  \
165e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher },   \
166e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
167e1051a39Sopenharmony_ci      (void (*)(void)) alg##_##kbits##_##lcmode##_get_params },                \
168e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
169e1051a39Sopenharmony_ci      (void (*)(void))ossl_cipher_generic_gettable_params },                   \
170e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
171e1051a39Sopenharmony_ci      (void (*)(void))rc5_get_ctx_params },                                    \
172e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
173e1051a39Sopenharmony_ci      (void (*)(void))rc5_gettable_ctx_params },                               \
174e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
175e1051a39Sopenharmony_ci      (void (*)(void))rc5_set_ctx_params },                                    \
176e1051a39Sopenharmony_ci    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
177e1051a39Sopenharmony_ci     (void (*)(void))rc5_settable_ctx_params },                                \
178e1051a39Sopenharmony_ci    { 0, NULL }                                                                \
179e1051a39Sopenharmony_ci};
180e1051a39Sopenharmony_ci
181e1051a39Sopenharmony_ci/* ossl_rc5128ecb_functions */
182e1051a39Sopenharmony_ciIMPLEMENT_cipher(rc5, RC5, ecb, ECB, RC5_FLAGS, 128, 64, 0, block)
183e1051a39Sopenharmony_ci/* ossl_rc5128cbc_functions */
184e1051a39Sopenharmony_ciIMPLEMENT_cipher(rc5, RC5, cbc, CBC, RC5_FLAGS, 128, 64, 64, block)
185e1051a39Sopenharmony_ci/* ossl_rc5128ofb64_functions */
186e1051a39Sopenharmony_ciIMPLEMENT_cipher(rc5, RC5, ofb64, OFB, RC5_FLAGS, 128, 8, 64, stream)
187e1051a39Sopenharmony_ci/* ossl_rc5128cfb64_functions */
188e1051a39Sopenharmony_ciIMPLEMENT_cipher(rc5, RC5, cfb64,  CFB, RC5_FLAGS, 128, 8, 64, stream)
189