168651Skris/* crypto/evp/e_des.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 6868651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 69280304Sjkim const unsigned char *iv, int enc); 70160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 7168651Skris 72280304Sjkim/* 73280304Sjkim * Because of various casts and different names can't use 74280304Sjkim * IMPLEMENT_BLOCK_CIPHER 75280304Sjkim */ 7668651Skris 7768651Skrisstatic int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 78280304Sjkim const unsigned char *in, size_t inl) 7968651Skris{ 80280304Sjkim BLOCK_CIPHER_ecb_loop() 81280304Sjkim DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), 82280304Sjkim ctx->cipher_data, ctx->encrypt); 83280304Sjkim return 1; 8468651Skris} 8568651Skris 8668651Skrisstatic int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 87280304Sjkim const unsigned char *in, size_t inl) 8868651Skris{ 89280304Sjkim while (inl >= EVP_MAXCHUNK) { 90280304Sjkim DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 91280304Sjkim (DES_cblock *)ctx->iv, &ctx->num); 92280304Sjkim inl -= EVP_MAXCHUNK; 93280304Sjkim in += EVP_MAXCHUNK; 94280304Sjkim out += EVP_MAXCHUNK; 95280304Sjkim } 96280304Sjkim if (inl) 97280304Sjkim DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, 98280304Sjkim (DES_cblock *)ctx->iv, &ctx->num); 99280304Sjkim return 1; 10068651Skris} 10168651Skris 10268651Skrisstatic int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 103280304Sjkim const unsigned char *in, size_t inl) 10468651Skris{ 105280304Sjkim while (inl >= EVP_MAXCHUNK) { 106280304Sjkim DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 107280304Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 108280304Sjkim inl -= EVP_MAXCHUNK; 109280304Sjkim in += EVP_MAXCHUNK; 110280304Sjkim out += EVP_MAXCHUNK; 111280304Sjkim } 112280304Sjkim if (inl) 113280304Sjkim DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, 114280304Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 115280304Sjkim return 1; 11668651Skris} 11768651Skris 118142425Snectarstatic int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 119280304Sjkim const unsigned char *in, size_t inl) 12068651Skris{ 121280304Sjkim while (inl >= EVP_MAXCHUNK) { 122280304Sjkim DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 123280304Sjkim (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 124280304Sjkim inl -= EVP_MAXCHUNK; 125280304Sjkim in += EVP_MAXCHUNK; 126280304Sjkim out += EVP_MAXCHUNK; 127280304Sjkim } 128280304Sjkim if (inl) 129280304Sjkim DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, 130280304Sjkim (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 131280304Sjkim return 1; 13268651Skris} 13368651Skris 134280304Sjkim/* 135280304Sjkim * Although we have a CFB-r implementation for DES, it doesn't pack the right 136280304Sjkim * way, so wrap it here 137280304Sjkim */ 138142425Snectarstatic int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 139280304Sjkim const unsigned char *in, size_t inl) 140280304Sjkim{ 141280304Sjkim size_t n, chunk = EVP_MAXCHUNK / 8; 142280304Sjkim unsigned char c[1], d[1]; 143142425Snectar 144280304Sjkim if (inl < chunk) 145280304Sjkim chunk = inl; 146238405Sjkim 147280304Sjkim while (inl && inl >= chunk) { 148280304Sjkim for (n = 0; n < chunk * 8; ++n) { 149280304Sjkim c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 150280304Sjkim DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, 151280304Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 152280304Sjkim out[n / 8] = 153280304Sjkim (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | 154280304Sjkim ((d[0] & 0x80) >> (unsigned int)(n % 8)); 155280304Sjkim } 156280304Sjkim inl -= chunk; 157280304Sjkim in += chunk; 158280304Sjkim out += chunk; 159280304Sjkim if (inl < chunk) 160280304Sjkim chunk = inl; 161280304Sjkim } 162238405Sjkim 163142425Snectar return 1; 164280304Sjkim} 165142425Snectar 166142425Snectarstatic int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 167280304Sjkim const unsigned char *in, size_t inl) 168280304Sjkim{ 169280304Sjkim while (inl >= EVP_MAXCHUNK) { 170280304Sjkim DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data, 171280304Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 172280304Sjkim inl -= EVP_MAXCHUNK; 173280304Sjkim in += EVP_MAXCHUNK; 174280304Sjkim out += EVP_MAXCHUNK; 175280304Sjkim } 176238405Sjkim if (inl) 177280304Sjkim DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, 178280304Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 179142425Snectar return 1; 180280304Sjkim} 181142425Snectar 182109998SmarkmBLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, 183280304Sjkim EVP_CIPH_RAND_KEY, des_init_key, NULL, 184280304Sjkim EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 18568651Skris 18668651Skris 187280304SjkimBLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 1, 188280304Sjkim EVP_CIPH_RAND_KEY, des_init_key, NULL, 189280304Sjkim EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 190142425Snectar 191280304SjkimBLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 8, 192280304Sjkim EVP_CIPH_RAND_KEY, des_init_key, NULL, 193280304Sjkim EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 194280304Sjkim 19568651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 196280304Sjkim const unsigned char *iv, int enc) 197280304Sjkim{ 198280304Sjkim DES_cblock *deskey = (DES_cblock *)key; 199280304Sjkim# ifdef EVP_CHECK_DES_KEY 200280304Sjkim if (DES_set_key_checked(deskey, ctx->cipher_data) != 0) 201280304Sjkim return 0; 202280304Sjkim# else 203280304Sjkim DES_set_key_unchecked(deskey, ctx->cipher_data); 204280304Sjkim# endif 205280304Sjkim return 1; 206280304Sjkim} 20768651Skris 208160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 209280304Sjkim{ 210160814Ssimon 211280304Sjkim switch (type) { 212280304Sjkim case EVP_CTRL_RAND_KEY: 213280304Sjkim if (RAND_bytes(ptr, 8) <= 0) 214280304Sjkim return 0; 215280304Sjkim DES_set_odd_parity((DES_cblock *)ptr); 216280304Sjkim return 1; 217160814Ssimon 218280304Sjkim default: 219280304Sjkim return -1; 220280304Sjkim } 221280304Sjkim} 222280304Sjkim 22368651Skris#endif 224