e_cast.c revision 1.18
1234285Sdim/* $OpenBSD: e_cast.c,v 1.18 2024/04/09 13:52:41 beck Exp $ */
2234285Sdim/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3234285Sdim * All rights reserved.
4234285Sdim *
5234285Sdim * This package is an SSL implementation written
6234285Sdim * by Eric Young (eay@cryptsoft.com).
7234285Sdim * The implementation was written so as to conform with Netscapes SSL.
8234285Sdim *
9234285Sdim * This library is free for commercial and non-commercial use as long as
10234285Sdim * the following conditions are aheared to.  The following conditions
11234285Sdim * apply to all code found in this distribution, be it the RC4, RSA,
12234285Sdim * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13234285Sdim * included with this distribution is covered by the same copyright terms
14234285Sdim * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15234285Sdim *
16234285Sdim * Copyright remains Eric Young's, and as such any Copyright notices in
17234285Sdim * the code are not to be removed.
18234285Sdim * If this package is used in a product, Eric Young should be given attribution
19251662Sdim * as the author of the parts of the library used.
20249423Sdim * This can be in the form of a textual message at program startup or
21251662Sdim * in documentation (online or textual) provided with the package.
22234285Sdim *
23234285Sdim * Redistribution and use in source and binary forms, with or without
24234285Sdim * modification, are permitted provided that the following conditions
25234285Sdim * are met:
26234285Sdim * 1. Redistributions of source code must retain the copyright
27234285Sdim *    notice, this list of conditions and the following disclaimer.
28234285Sdim * 2. Redistributions in binary form must reproduce the above copyright
29263508Sdim *    notice, this list of conditions and the following disclaimer in the
30234285Sdim *    documentation and/or other materials provided with the distribution.
31263508Sdim * 3. All advertising materials mentioning features or use of this software
32251662Sdim *    must display the following acknowledgement:
33251662Sdim *    "This product includes cryptographic software written by
34234285Sdim *     Eric Young (eay@cryptsoft.com)"
35234285Sdim *    The word 'cryptographic' can be left out if the rouines from the library
36234285Sdim *    being used are not cryptographic related :-).
37234285Sdim * 4. If you include any Windows specific code (or a derivative thereof) from
38234285Sdim *    the apps directory (application code) you must include an acknowledgement:
39234285Sdim *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40234285Sdim *
41234285Sdim * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42234285Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43234285Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44234285Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45234285Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46234285Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47234285Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48234285Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49234285Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50234285Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51234285Sdim * SUCH DAMAGE.
52234285Sdim *
53234285Sdim * The licence and distribution terms for any publically available version or
54234285Sdim * derivative of this code cannot be changed.  i.e. this code cannot simply be
55234285Sdim * copied and put under another distribution licence
56234285Sdim * [including the GNU Public Licence.]
57234285Sdim */
58234285Sdim
59234285Sdim#include <limits.h>
60234285Sdim#include <stdio.h>
61234285Sdim
62234285Sdim#include <openssl/opensslconf.h>
63234285Sdim
64234285Sdim#ifndef OPENSSL_NO_CAST
65234285Sdim
66234285Sdim#include <openssl/cast.h>
67234285Sdim#include <openssl/evp.h>
68234285Sdim#include <openssl/objects.h>
69234285Sdim
70234285Sdim#include "evp_local.h"
71234285Sdim
72249423Sdimtypedef struct {
73249423Sdim	CAST_KEY ks;
74249423Sdim} EVP_CAST_KEY;
75249423Sdim
76234285Sdim#define data(ctx)	((EVP_CAST_KEY *)(ctx)->cipher_data)
77234285Sdim
78234285Sdimstatic int
79234285Sdimcast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
80234285Sdim    const unsigned char *iv, int enc)
81234285Sdim{
82234285Sdim	CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
83234285Sdim	return 1;
84234285Sdim}
85234285Sdim
86234285Sdimstatic int
87234285Sdimcast5_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
88234285Sdim{
89234285Sdim	size_t chunk = LONG_MAX & ~0xff;
90234285Sdim
91234285Sdim	while (inl >= chunk) {
92234285Sdim		CAST_cbc_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
93234285Sdim		inl -= chunk;
94234285Sdim		in += chunk;
95234285Sdim		out += chunk;
96234285Sdim	}
97234285Sdim
98234285Sdim	if (inl)
99234285Sdim		CAST_cbc_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
100234285Sdim
101234285Sdim	return 1;
102234285Sdim}
103234285Sdim
104234285Sdimstatic int
105234285Sdimcast5_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
106234285Sdim{
107234285Sdim	size_t chunk = LONG_MAX & ~0xff;
108234285Sdim
109234285Sdim	if (inl < chunk)
110234285Sdim		chunk = inl;
111234285Sdim
112234285Sdim	while (inl && inl >= chunk) {
113234285Sdim		CAST_cfb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
114234285Sdim		inl -= chunk;
115234285Sdim		in += chunk;
116234285Sdim		out += chunk;
117251662Sdim		if (inl < chunk)
118234285Sdim			chunk = inl;
119234285Sdim	}
120234285Sdim
121234285Sdim	return 1;
122234285Sdim}
123239462Sdim
124234285Sdimstatic int
125234285Sdimcast5_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
126234285Sdim{
127234285Sdim	size_t i, bl;
128234285Sdim
129234285Sdim	bl = ctx->cipher->block_size;
130234285Sdim
131234285Sdim	if (inl < bl)
132234285Sdim		return 1;
133234285Sdim
134251662Sdim	inl -= bl;
135251662Sdim
136251662Sdim	for (i = 0; i <= inl; i += bl)
137249423Sdim		CAST_ecb_encrypt(in + i, out + i, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
138251662Sdim
139234285Sdim	return 1;
140234285Sdim}
141234285Sdim
142234285Sdimstatic int
143234285Sdimcast5_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
144234285Sdim{
145234285Sdim	size_t chunk = LONG_MAX & ~0xff;
146234285Sdim
147234285Sdim	while (inl >= chunk) {
148234285Sdim		CAST_ofb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
149234285Sdim		inl -= chunk;
150234285Sdim		in += chunk;
151234285Sdim		out += chunk;
152234285Sdim	}
153234285Sdim
154234285Sdim	if (inl)
155234285Sdim		CAST_ofb64_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
156234285Sdim
157234285Sdim	return 1;
158234285Sdim}
159234285Sdim
160234285Sdimstatic const EVP_CIPHER cast5_cbc = {
161234285Sdim	.nid = NID_cast5_cbc,
162234285Sdim	.block_size = 8,
163234285Sdim	.key_len = CAST_KEY_LENGTH,
164234285Sdim	.iv_len = 8,
165234285Sdim	.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
166234285Sdim	.init = cast_init_key,
167234285Sdim	.do_cipher = cast5_cbc_cipher,
168234285Sdim	.cleanup = NULL,
169234285Sdim	.ctx_size = sizeof(EVP_CAST_KEY),
170234285Sdim	.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
171234285Sdim	.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
172234285Sdim	.ctrl = NULL,
173234285Sdim};
174234285Sdim
175234285Sdimconst EVP_CIPHER *
176239462SdimEVP_cast5_cbc(void)
177239462Sdim{
178234285Sdim	return &cast5_cbc;
179234285Sdim}
180239462SdimLCRYPTO_ALIAS(EVP_cast5_cbc);
181249423Sdim
182251662Sdimstatic const EVP_CIPHER cast5_cfb64 = {
183249423Sdim	.nid = NID_cast5_cfb64,
184263508Sdim	.block_size = 1,
185263508Sdim	.key_len = CAST_KEY_LENGTH,
186263508Sdim	.iv_len = 8,
187263508Sdim	.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE,
188263508Sdim	.init = cast_init_key,
189263508Sdim	.do_cipher = cast5_cfb64_cipher,
190234285Sdim	.cleanup = NULL,
191234285Sdim	.ctx_size = sizeof(EVP_CAST_KEY),
192239462Sdim	.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
193239462Sdim	.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
194239462Sdim	.ctrl = NULL,
195239462Sdim};
196263508Sdim
197239462Sdimconst EVP_CIPHER *
198239462SdimEVP_cast5_cfb64(void)
199234285Sdim{
200249423Sdim	return &cast5_cfb64;
201249423Sdim}
202249423SdimLCRYPTO_ALIAS(EVP_cast5_cfb64);
203251662Sdim
204251662Sdimstatic const EVP_CIPHER cast5_ofb = {
205249423Sdim	.nid = NID_cast5_ofb64,
206249423Sdim	.block_size = 1,
207249423Sdim	.key_len = CAST_KEY_LENGTH,
208249423Sdim	.iv_len = 8,
209249423Sdim	.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE,
210249423Sdim	.init = cast_init_key,
211249423Sdim	.do_cipher = cast5_ofb_cipher,
212249423Sdim	.cleanup = NULL,
213251662Sdim	.ctx_size = sizeof(EVP_CAST_KEY),
214251662Sdim	.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
215251662Sdim	.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
216234285Sdim	.ctrl = NULL,
217234285Sdim};
218234285Sdim
219234285Sdimconst EVP_CIPHER *
220234285SdimEVP_cast5_ofb(void)
221234285Sdim{
222234285Sdim	return &cast5_ofb;
223234285Sdim}
224LCRYPTO_ALIAS(EVP_cast5_ofb);
225
226static const EVP_CIPHER cast5_ecb = {
227	.nid = NID_cast5_ecb,
228	.block_size = 8,
229	.key_len = CAST_KEY_LENGTH,
230	.iv_len = 0,
231	.flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE,
232	.init = cast_init_key,
233	.do_cipher = cast5_ecb_cipher,
234	.cleanup = NULL,
235	.ctx_size = sizeof(EVP_CAST_KEY),
236	.set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
237	.get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
238	.ctrl = NULL,
239};
240
241const EVP_CIPHER *
242EVP_cast5_ecb(void)
243{
244	return &cast5_ecb;
245}
246LCRYPTO_ALIAS(EVP_cast5_ecb);
247#endif
248