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