1*9bac3682Sbeck /* $OpenBSD: e_cast.c,v 1.18 2024/04/09 13:52:41 beck Exp $ */
2c109e398Sbeck /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3c109e398Sbeck * All rights reserved.
4c109e398Sbeck *
5c109e398Sbeck * This package is an SSL implementation written
6c109e398Sbeck * by Eric Young (eay@cryptsoft.com).
7c109e398Sbeck * The implementation was written so as to conform with Netscapes SSL.
8c109e398Sbeck *
9c109e398Sbeck * This library is free for commercial and non-commercial use as long as
10c109e398Sbeck * the following conditions are aheared to. The following conditions
11c109e398Sbeck * apply to all code found in this distribution, be it the RC4, RSA,
12c109e398Sbeck * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13c109e398Sbeck * included with this distribution is covered by the same copyright terms
14c109e398Sbeck * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15c109e398Sbeck *
16c109e398Sbeck * Copyright remains Eric Young's, and as such any Copyright notices in
17c109e398Sbeck * the code are not to be removed.
18c109e398Sbeck * If this package is used in a product, Eric Young should be given attribution
19c109e398Sbeck * as the author of the parts of the library used.
20c109e398Sbeck * This can be in the form of a textual message at program startup or
21c109e398Sbeck * in documentation (online or textual) provided with the package.
22c109e398Sbeck *
23c109e398Sbeck * Redistribution and use in source and binary forms, with or without
24c109e398Sbeck * modification, are permitted provided that the following conditions
25c109e398Sbeck * are met:
26c109e398Sbeck * 1. Redistributions of source code must retain the copyright
27c109e398Sbeck * notice, this list of conditions and the following disclaimer.
28c109e398Sbeck * 2. Redistributions in binary form must reproduce the above copyright
29c109e398Sbeck * notice, this list of conditions and the following disclaimer in the
30c109e398Sbeck * documentation and/or other materials provided with the distribution.
31c109e398Sbeck * 3. All advertising materials mentioning features or use of this software
32c109e398Sbeck * must display the following acknowledgement:
33c109e398Sbeck * "This product includes cryptographic software written by
34c109e398Sbeck * Eric Young (eay@cryptsoft.com)"
35c109e398Sbeck * The word 'cryptographic' can be left out if the rouines from the library
36c109e398Sbeck * being used are not cryptographic related :-).
37c109e398Sbeck * 4. If you include any Windows specific code (or a derivative thereof) from
38c109e398Sbeck * the apps directory (application code) you must include an acknowledgement:
39c109e398Sbeck * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40c109e398Sbeck *
41c109e398Sbeck * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42c109e398Sbeck * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43c109e398Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44c109e398Sbeck * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45c109e398Sbeck * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46c109e398Sbeck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47c109e398Sbeck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48c109e398Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49c109e398Sbeck * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50c109e398Sbeck * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51c109e398Sbeck * SUCH DAMAGE.
52c109e398Sbeck *
53c109e398Sbeck * The licence and distribution terms for any publically available version or
54c109e398Sbeck * derivative of this code cannot be changed. i.e. this code cannot simply be
55c109e398Sbeck * copied and put under another distribution licence
56c109e398Sbeck * [including the GNU Public Licence.]
57c109e398Sbeck */
58c109e398Sbeck
59b76ab7f9Sjsing #include <limits.h>
60c109e398Sbeck #include <stdio.h>
618cf4d6a6Sjsing
628cf4d6a6Sjsing #include <openssl/opensslconf.h>
638cf4d6a6Sjsing
644fcf65c5Sdjm #ifndef OPENSSL_NO_CAST
65b6ab114eSjsing
66b6ab114eSjsing #include <openssl/cast.h>
67c109e398Sbeck #include <openssl/evp.h>
68c109e398Sbeck #include <openssl/objects.h>
69b6ab114eSjsing
70c9675a23Stb #include "evp_local.h"
71c109e398Sbeck
72ba3920edSjsing typedef struct {
73da347917Sbeck CAST_KEY ks;
74da347917Sbeck } EVP_CAST_KEY;
75da347917Sbeck
769912564aSjsing #define data(ctx) ((EVP_CAST_KEY *)(ctx)->cipher_data)
77da347917Sbeck
789912564aSjsing static int
cast_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)795b4a16c0Sjsing cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
805b4a16c0Sjsing const unsigned char *iv, int enc)
815b4a16c0Sjsing {
825b4a16c0Sjsing CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
835b4a16c0Sjsing return 1;
845b4a16c0Sjsing }
855b4a16c0Sjsing
865b4a16c0Sjsing static int
cast5_cbc_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)879912564aSjsing cast5_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
889912564aSjsing {
89fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
90b76ab7f9Sjsing
91fa590012Sjsing while (inl >= chunk) {
92fa590012Sjsing CAST_cbc_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
93fa590012Sjsing inl -= chunk;
94fa590012Sjsing in += chunk;
95fa590012Sjsing out += chunk;
969912564aSjsing }
979912564aSjsing
989912564aSjsing if (inl)
999912564aSjsing CAST_cbc_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
1009912564aSjsing
1019912564aSjsing return 1;
1029912564aSjsing }
1039912564aSjsing
1049912564aSjsing static int
cast5_cfb64_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1059912564aSjsing cast5_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1069912564aSjsing {
107fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
108b76ab7f9Sjsing
1099912564aSjsing if (inl < chunk)
1109912564aSjsing chunk = inl;
1119912564aSjsing
1129912564aSjsing while (inl && inl >= chunk) {
1137a606269Sjsing CAST_cfb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
1149912564aSjsing inl -= chunk;
1159912564aSjsing in += chunk;
1169912564aSjsing out += chunk;
1179912564aSjsing if (inl < chunk)
1189912564aSjsing chunk = inl;
1199912564aSjsing }
1209912564aSjsing
1219912564aSjsing return 1;
1229912564aSjsing }
1239912564aSjsing
1249912564aSjsing static int
cast5_ecb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1259912564aSjsing cast5_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1269912564aSjsing {
1279912564aSjsing size_t i, bl;
1289912564aSjsing
1299912564aSjsing bl = ctx->cipher->block_size;
1309912564aSjsing
1319912564aSjsing if (inl < bl)
1329912564aSjsing return 1;
1339912564aSjsing
1349912564aSjsing inl -= bl;
1359912564aSjsing
1369912564aSjsing for (i = 0; i <= inl; i += bl)
1379912564aSjsing CAST_ecb_encrypt(in + i, out + i, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
1389912564aSjsing
1399912564aSjsing return 1;
1409912564aSjsing }
1419912564aSjsing
1429912564aSjsing static int
cast5_ofb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1439912564aSjsing cast5_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1449912564aSjsing {
145fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
146b76ab7f9Sjsing
147fa590012Sjsing while (inl >= chunk) {
148fa590012Sjsing CAST_ofb64_encrypt(in, out, (long)chunk, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
149fa590012Sjsing inl -= chunk;
150fa590012Sjsing in += chunk;
151fa590012Sjsing out += chunk;
1529912564aSjsing }
1539912564aSjsing
1549912564aSjsing if (inl)
1559912564aSjsing CAST_ofb64_encrypt(in, out, (long)inl, &((EVP_CAST_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
1569912564aSjsing
1579912564aSjsing return 1;
1589912564aSjsing }
1599912564aSjsing
1609912564aSjsing static const EVP_CIPHER cast5_cbc = {
1619912564aSjsing .nid = NID_cast5_cbc,
1629912564aSjsing .block_size = 8,
1639912564aSjsing .key_len = CAST_KEY_LENGTH,
1649912564aSjsing .iv_len = 8,
1659912564aSjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
1669912564aSjsing .init = cast_init_key,
1679912564aSjsing .do_cipher = cast5_cbc_cipher,
1689912564aSjsing .cleanup = NULL,
1699912564aSjsing .ctx_size = sizeof(EVP_CAST_KEY),
1709912564aSjsing .set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
1719912564aSjsing .get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
1729912564aSjsing .ctrl = NULL,
1739912564aSjsing };
1749912564aSjsing
1759912564aSjsing const EVP_CIPHER *
EVP_cast5_cbc(void)1769912564aSjsing EVP_cast5_cbc(void)
1779912564aSjsing {
1789912564aSjsing return &cast5_cbc;
1799912564aSjsing }
180*9bac3682Sbeck LCRYPTO_ALIAS(EVP_cast5_cbc);
1819912564aSjsing
1829912564aSjsing static const EVP_CIPHER cast5_cfb64 = {
1839912564aSjsing .nid = NID_cast5_cfb64,
1849912564aSjsing .block_size = 1,
1859912564aSjsing .key_len = CAST_KEY_LENGTH,
1869912564aSjsing .iv_len = 8,
1879912564aSjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CFB_MODE,
1889912564aSjsing .init = cast_init_key,
1899912564aSjsing .do_cipher = cast5_cfb64_cipher,
1909912564aSjsing .cleanup = NULL,
1919912564aSjsing .ctx_size = sizeof(EVP_CAST_KEY),
1929912564aSjsing .set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
1939912564aSjsing .get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
1949912564aSjsing .ctrl = NULL,
1959912564aSjsing };
1969912564aSjsing
1979912564aSjsing const EVP_CIPHER *
EVP_cast5_cfb64(void)1989912564aSjsing EVP_cast5_cfb64(void)
1999912564aSjsing {
2009912564aSjsing return &cast5_cfb64;
2019912564aSjsing }
202*9bac3682Sbeck LCRYPTO_ALIAS(EVP_cast5_cfb64);
2039912564aSjsing
2049912564aSjsing static const EVP_CIPHER cast5_ofb = {
2059912564aSjsing .nid = NID_cast5_ofb64,
2069912564aSjsing .block_size = 1,
2079912564aSjsing .key_len = CAST_KEY_LENGTH,
2089912564aSjsing .iv_len = 8,
2099912564aSjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_OFB_MODE,
2109912564aSjsing .init = cast_init_key,
2119912564aSjsing .do_cipher = cast5_ofb_cipher,
2129912564aSjsing .cleanup = NULL,
2139912564aSjsing .ctx_size = sizeof(EVP_CAST_KEY),
2149912564aSjsing .set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
2159912564aSjsing .get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
2169912564aSjsing .ctrl = NULL,
2179912564aSjsing };
2189912564aSjsing
2199912564aSjsing const EVP_CIPHER *
EVP_cast5_ofb(void)2209912564aSjsing EVP_cast5_ofb(void)
2219912564aSjsing {
2229912564aSjsing return &cast5_ofb;
2239912564aSjsing }
224*9bac3682Sbeck LCRYPTO_ALIAS(EVP_cast5_ofb);
2259912564aSjsing
2269912564aSjsing static const EVP_CIPHER cast5_ecb = {
2279912564aSjsing .nid = NID_cast5_ecb,
2289912564aSjsing .block_size = 8,
2299912564aSjsing .key_len = CAST_KEY_LENGTH,
2309912564aSjsing .iv_len = 0,
2319912564aSjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ECB_MODE,
2329912564aSjsing .init = cast_init_key,
2339912564aSjsing .do_cipher = cast5_ecb_cipher,
2349912564aSjsing .cleanup = NULL,
2359912564aSjsing .ctx_size = sizeof(EVP_CAST_KEY),
2369912564aSjsing .set_asn1_parameters = EVP_CIPHER_set_asn1_iv,
2379912564aSjsing .get_asn1_parameters = EVP_CIPHER_get_asn1_iv,
2389912564aSjsing .ctrl = NULL,
2399912564aSjsing };
2409912564aSjsing
2419912564aSjsing const EVP_CIPHER *
EVP_cast5_ecb(void)2429912564aSjsing EVP_cast5_ecb(void)
2439912564aSjsing {
2449912564aSjsing return &cast5_ecb;
2459912564aSjsing }
246*9bac3682Sbeck LCRYPTO_ALIAS(EVP_cast5_ecb);
247c109e398Sbeck #endif
248