168651Skris/* crypto/evp/e_des3.c */ 268651Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 368651Skris * All rights reserved. 468651Skris * 568651Skris * This package is an SSL implementation written 668651Skris * by Eric Young (eay@cryptsoft.com). 768651Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 968651Skris * This library is free for commercial and non-commercial use as long as 1068651Skris * the following conditions are aheared to. The following conditions 1168651Skris * apply to all code found in this distribution, be it the RC4, RSA, 1268651Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1368651Skris * included with this distribution is covered by the same copyright terms 1468651Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1668651Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1768651Skris * the code are not to be removed. 1868651Skris * If this package is used in a product, Eric Young should be given attribution 1968651Skris * as the author of the parts of the library used. 2068651Skris * This can be in the form of a textual message at program startup or 2168651Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2368651Skris * Redistribution and use in source and binary forms, with or without 2468651Skris * modification, are permitted provided that the following conditions 2568651Skris * are met: 2668651Skris * 1. Redistributions of source code must retain the copyright 2768651Skris * notice, this list of conditions and the following disclaimer. 2868651Skris * 2. Redistributions in binary form must reproduce the above copyright 2968651Skris * notice, this list of conditions and the following disclaimer in the 3068651Skris * documentation and/or other materials provided with the distribution. 3168651Skris * 3. All advertising materials mentioning features or use of this software 3268651Skris * must display the following acknowledgement: 3368651Skris * "This product includes cryptographic software written by 3468651Skris * Eric Young (eay@cryptsoft.com)" 3568651Skris * The word 'cryptographic' can be left out if the rouines from the library 3668651Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3868651Skris * the apps directory (application code) you must include an acknowledgement: 3968651Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4168651Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4268651Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4368651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4468651Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4568651Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4668651Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4768651Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4968651Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5068651Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5168651Skris * SUCH DAMAGE. 52280304Sjkim * 5368651Skris * The licence and distribution terms for any publically available version or 5468651Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5568651Skris * copied and put under another distribution licence 5668651Skris * [including the GNU Public Licence.] 5768651Skris */ 5868651Skris 5968651Skris#include <stdio.h> 6068651Skris#include "cryptlib.h" 61142425Snectar#ifndef OPENSSL_NO_DES 62280304Sjkim# include <openssl/evp.h> 63280304Sjkim# include <openssl/objects.h> 64280304Sjkim# include "evp_locl.h" 65280304Sjkim# include <openssl/des.h> 66280304Sjkim# include <openssl/rand.h> 6768651Skris 68280304Sjkim# ifndef OPENSSL_FIPS 69238405Sjkim 7068651Skrisstatic int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 71280304Sjkim const unsigned char *iv, int enc); 7268651Skris 7368651Skrisstatic int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 74280304Sjkim const unsigned char *iv, int enc); 7568651Skris 76160814Ssimonstatic int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 77160814Ssimon 78280304Sjkimtypedef struct { 79280304Sjkim DES_key_schedule ks1; /* key schedule */ 80280304Sjkim DES_key_schedule ks2; /* key schedule (for ede) */ 81280304Sjkim DES_key_schedule ks3; /* key schedule (for ede3) */ 82280304Sjkim} DES_EDE_KEY; 83109998Smarkm 84280304Sjkim# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) 85109998Smarkm 86280304Sjkim/* 87280304Sjkim * Because of various casts and different args can't use 88280304Sjkim * IMPLEMENT_BLOCK_CIPHER 89280304Sjkim */ 9068651Skris 9168651Skrisstatic int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 92280304Sjkim const unsigned char *in, size_t inl) 9368651Skris{ 94280304Sjkim BLOCK_CIPHER_ecb_loop() 95280304Sjkim DES_ecb3_encrypt((const_DES_cblock *)(in + i), 96280304Sjkim (DES_cblock *)(out + i), 97280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 98280304Sjkim &data(ctx)->ks3, ctx->encrypt); 99280304Sjkim return 1; 10068651Skris} 10168651Skris 10268651Skrisstatic int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 103280304Sjkim const unsigned char *in, size_t inl) 10468651Skris{ 105280304Sjkim while (inl >= EVP_MAXCHUNK) { 106280304Sjkim DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, 107280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 108280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 109280304Sjkim &ctx->num); 110280304Sjkim inl -= EVP_MAXCHUNK; 111280304Sjkim in += EVP_MAXCHUNK; 112280304Sjkim out += EVP_MAXCHUNK; 113280304Sjkim } 114280304Sjkim if (inl) 115280304Sjkim DES_ede3_ofb64_encrypt(in, out, (long)inl, 116280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 117280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 118280304Sjkim &ctx->num); 119238405Sjkim 120280304Sjkim return 1; 12168651Skris} 12268651Skris 12368651Skrisstatic int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 124280304Sjkim const unsigned char *in, size_t inl) 12568651Skris{ 126280304Sjkim# ifdef KSSL_DEBUG 127280304Sjkim { 128109998Smarkm int i; 129280304Sjkim fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, 130280304Sjkim ctx->buf_len); 131280304Sjkim fprintf(stderr, "\t iv= "); 132280304Sjkim for (i = 0; i < 8; i++) 133280304Sjkim fprintf(stderr, "%02X", ctx->iv[i]); 134280304Sjkim fprintf(stderr, "\n"); 135280304Sjkim } 136280304Sjkim# endif /* KSSL_DEBUG */ 137280304Sjkim while (inl >= EVP_MAXCHUNK) { 138280304Sjkim DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, 139280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 140280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 141280304Sjkim ctx->encrypt); 142280304Sjkim inl -= EVP_MAXCHUNK; 143280304Sjkim in += EVP_MAXCHUNK; 144280304Sjkim out += EVP_MAXCHUNK; 145280304Sjkim } 146280304Sjkim if (inl) 147280304Sjkim DES_ede3_cbc_encrypt(in, out, (long)inl, 148280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 149280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 150280304Sjkim ctx->encrypt); 151280304Sjkim return 1; 15268651Skris} 15368651Skris 154142425Snectarstatic int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 155280304Sjkim const unsigned char *in, size_t inl) 15668651Skris{ 157280304Sjkim while (inl >= EVP_MAXCHUNK) { 158280304Sjkim DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 159280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 160280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 161280304Sjkim &ctx->num, ctx->encrypt); 162280304Sjkim inl -= EVP_MAXCHUNK; 163280304Sjkim in += EVP_MAXCHUNK; 164280304Sjkim out += EVP_MAXCHUNK; 165280304Sjkim } 166280304Sjkim if (inl) 167280304Sjkim DES_ede3_cfb64_encrypt(in, out, (long)inl, 168280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 169280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 170280304Sjkim &ctx->num, ctx->encrypt); 171280304Sjkim return 1; 17268651Skris} 17368651Skris 174280304Sjkim/* 175280304Sjkim * Although we have a CFB-r implementation for 3-DES, it doesn't pack the 176280304Sjkim * right way, so wrap it here 177280304Sjkim */ 178142425Snectarstatic int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 179280304Sjkim const unsigned char *in, size_t inl) 180280304Sjkim{ 181238405Sjkim size_t n; 182280304Sjkim unsigned char c[1], d[1]; 183142425Snectar 184280304Sjkim for (n = 0; n < inl; ++n) { 185280304Sjkim c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 186280304Sjkim DES_ede3_cfb_encrypt(c, d, 1, 1, 187280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 188280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 189280304Sjkim ctx->encrypt); 190280304Sjkim out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) 191280304Sjkim | ((d[0] & 0x80) >> (unsigned int)(n % 8)); 192280304Sjkim } 193142425Snectar 194142425Snectar return 1; 195280304Sjkim} 196142425Snectar 197142425Snectarstatic int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 198280304Sjkim const unsigned char *in, size_t inl) 199280304Sjkim{ 200280304Sjkim while (inl >= EVP_MAXCHUNK) { 201280304Sjkim DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, 202280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 203280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 204280304Sjkim ctx->encrypt); 205280304Sjkim inl -= EVP_MAXCHUNK; 206280304Sjkim in += EVP_MAXCHUNK; 207280304Sjkim out += EVP_MAXCHUNK; 208280304Sjkim } 209238405Sjkim if (inl) 210280304Sjkim DES_ede3_cfb_encrypt(in, out, 8, (long)inl, 211280304Sjkim &data(ctx)->ks1, &data(ctx)->ks2, 212280304Sjkim &data(ctx)->ks3, (DES_cblock *)ctx->iv, 213280304Sjkim ctx->encrypt); 214142425Snectar return 1; 215280304Sjkim} 216142425Snectar 217109998SmarkmBLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, 218280304Sjkim EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, 219280304Sjkim EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) 220280304Sjkim# define des_ede3_cfb64_cipher des_ede_cfb64_cipher 221280304Sjkim# define des_ede3_ofb_cipher des_ede_ofb_cipher 222280304Sjkim# define des_ede3_cbc_cipher des_ede_cbc_cipher 223280304Sjkim# define des_ede3_ecb_cipher des_ede_ecb_cipher 224280304Sjkim BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, 225280304Sjkim EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 226280304Sjkim EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) 22768651Skris 228280304Sjkim BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, 229280304Sjkim EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 230280304Sjkim EVP_CIPHER_set_asn1_iv, 231280304Sjkim EVP_CIPHER_get_asn1_iv, des3_ctrl) 23268651Skris 233280304Sjkim BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, 234280304Sjkim EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 235280304Sjkim EVP_CIPHER_set_asn1_iv, 236280304Sjkim EVP_CIPHER_get_asn1_iv, des3_ctrl) 23768651Skris 23868651Skrisstatic int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 239280304Sjkim const unsigned char *iv, int enc) 240280304Sjkim{ 241280304Sjkim DES_cblock *deskey = (DES_cblock *)key; 242280304Sjkim# ifdef EVP_CHECK_DES_KEY 243280304Sjkim if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) 244291721Sjkim || DES_set_key_checked(&deskey[1], &data(ctx)->ks2)) 245280304Sjkim return 0; 246280304Sjkim# else 247280304Sjkim DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); 248280304Sjkim DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); 249280304Sjkim# endif 250280304Sjkim memcpy(&data(ctx)->ks3, &data(ctx)->ks1, sizeof(data(ctx)->ks1)); 251280304Sjkim return 1; 252280304Sjkim} 25368651Skris 25468651Skrisstatic int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 255280304Sjkim const unsigned char *iv, int enc) 256280304Sjkim{ 257280304Sjkim DES_cblock *deskey = (DES_cblock *)key; 258280304Sjkim# ifdef KSSL_DEBUG 259280304Sjkim { 260109998Smarkm int i; 261280304Sjkim fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx); 262280304Sjkim fprintf(stderr, "\tKEY= "); 263280304Sjkim for (i = 0; i < 24; i++) 264280304Sjkim fprintf(stderr, "%02X", key[i]); 265280304Sjkim fprintf(stderr, "\n"); 266280304Sjkim if (iv) { 267280304Sjkim fprintf(stderr, "\t IV= "); 268280304Sjkim for (i = 0; i < 8; i++) 269280304Sjkim fprintf(stderr, "%02X", iv[i]); 270280304Sjkim fprintf(stderr, "\n"); 271280304Sjkim } 272280304Sjkim } 273280304Sjkim# endif /* KSSL_DEBUG */ 27468651Skris 275280304Sjkim# ifdef EVP_CHECK_DES_KEY 276280304Sjkim if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) 277280304Sjkim || DES_set_key_checked(&deskey[1], &data(ctx)->ks2) 278280304Sjkim || DES_set_key_checked(&deskey[2], &data(ctx)->ks3)) 279280304Sjkim return 0; 280280304Sjkim# else 281280304Sjkim DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); 282280304Sjkim DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); 283280304Sjkim DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3); 284280304Sjkim# endif 285280304Sjkim return 1; 286280304Sjkim} 28768651Skris 288160814Ssimonstatic int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 289280304Sjkim{ 290160814Ssimon 291280304Sjkim DES_cblock *deskey = ptr; 292160814Ssimon 293280304Sjkim switch (type) { 294280304Sjkim case EVP_CTRL_RAND_KEY: 295280304Sjkim if (RAND_bytes(ptr, c->key_len) <= 0) 296280304Sjkim return 0; 297280304Sjkim DES_set_odd_parity(deskey); 298280304Sjkim if (c->key_len >= 16) 299280304Sjkim DES_set_odd_parity(deskey + 1); 300280304Sjkim if (c->key_len >= 24) 301280304Sjkim DES_set_odd_parity(deskey + 2); 302280304Sjkim return 1; 303160814Ssimon 304280304Sjkim default: 305280304Sjkim return -1; 306280304Sjkim } 307280304Sjkim} 308160814Ssimon 309109998Smarkmconst EVP_CIPHER *EVP_des_ede(void) 31068651Skris{ 311280304Sjkim return &des_ede_ecb; 31268651Skris} 31368651Skris 314109998Smarkmconst EVP_CIPHER *EVP_des_ede3(void) 31568651Skris{ 316280304Sjkim return &des_ede3_ecb; 31768651Skris} 318280304Sjkim# endif 31968651Skris#endif 320