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. 868651Skris * 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). 1568651Skris * 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. 2268651Skris * 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 :-). 3768651Skris * 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)" 4068651Skris * 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. 5268651Skris * 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 6268651Skris#include <openssl/evp.h> 6368651Skris#include <openssl/objects.h> 6468651Skris#include "evp_locl.h" 65109998Smarkm#include <openssl/des.h> 66160814Ssimon#include <openssl/rand.h> 6768651Skris 6868651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 6968651Skris const unsigned char *iv, int enc); 70160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 7168651Skris 7268651Skris/* Because of various casts and different names can't use IMPLEMENT_BLOCK_CIPHER */ 7368651Skris 7468651Skrisstatic int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 75238405Sjkim const unsigned char *in, size_t inl) 7668651Skris{ 7768651Skris BLOCK_CIPHER_ecb_loop() 78109998Smarkm DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), ctx->cipher_data, ctx->encrypt); 7968651Skris return 1; 8068651Skris} 8168651Skris 8268651Skrisstatic int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 83238405Sjkim const unsigned char *in, size_t inl) 8468651Skris{ 85238405Sjkim while(inl>=EVP_MAXCHUNK) 86238405Sjkim { 87238405Sjkim DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 88238405Sjkim (DES_cblock *)ctx->iv, &ctx->num); 89238405Sjkim inl-=EVP_MAXCHUNK; 90238405Sjkim in +=EVP_MAXCHUNK; 91238405Sjkim out+=EVP_MAXCHUNK; 92238405Sjkim } 93238405Sjkim if (inl) 94238405Sjkim DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, 95238405Sjkim (DES_cblock *)ctx->iv, &ctx->num); 9668651Skris return 1; 9768651Skris} 9868651Skris 9968651Skrisstatic int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 100238405Sjkim const unsigned char *in, size_t inl) 10168651Skris{ 102238405Sjkim while(inl>=EVP_MAXCHUNK) 103238405Sjkim { 104238405Sjkim DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 105238405Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 106238405Sjkim inl-=EVP_MAXCHUNK; 107238405Sjkim in +=EVP_MAXCHUNK; 108238405Sjkim out+=EVP_MAXCHUNK; 109238405Sjkim } 110238405Sjkim if (inl) 111238405Sjkim DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, 112238405Sjkim (DES_cblock *)ctx->iv, ctx->encrypt); 11368651Skris return 1; 11468651Skris} 11568651Skris 116142425Snectarstatic int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 117238405Sjkim const unsigned char *in, size_t inl) 11868651Skris{ 119238405Sjkim while(inl>=EVP_MAXCHUNK) 120238405Sjkim { 121238405Sjkim DES_cfb64_encrypt(in,out, (long)EVP_MAXCHUNK, ctx->cipher_data, 122238405Sjkim (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 123238405Sjkim inl-=EVP_MAXCHUNK; 124238405Sjkim in +=EVP_MAXCHUNK; 125238405Sjkim out+=EVP_MAXCHUNK; 126238405Sjkim } 127238405Sjkim if (inl) 128238405Sjkim DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, 129109998Smarkm (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 13068651Skris return 1; 13168651Skris} 13268651Skris 133142425Snectar/* Although we have a CFB-r implementation for DES, it doesn't pack the right 134142425Snectar way, so wrap it here */ 135142425Snectarstatic int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 136238405Sjkim const unsigned char *in, size_t inl) 137142425Snectar { 138238405Sjkim size_t n,chunk=EVP_MAXCHUNK/8; 139142425Snectar unsigned char c[1],d[1]; 140142425Snectar 141238405Sjkim if (inl<chunk) chunk=inl; 142238405Sjkim 143238405Sjkim while (inl && inl>=chunk) 144142425Snectar { 145238405Sjkim for(n=0 ; n < chunk*8; ++n) 146238405Sjkim { 147238405Sjkim c[0]=(in[n/8]&(1 << (7-n%8))) ? 0x80 : 0; 148238405Sjkim DES_cfb_encrypt(c,d,1,1,ctx->cipher_data,(DES_cblock *)ctx->iv, 149142425Snectar ctx->encrypt); 150238405Sjkim out[n/8]=(out[n/8]&~(0x80 >> (unsigned int)(n%8))) | 151238405Sjkim ((d[0]&0x80) >> (unsigned int)(n%8)); 152238405Sjkim } 153238405Sjkim inl-=chunk; 154238405Sjkim in +=chunk; 155238405Sjkim out+=chunk; 156238405Sjkim if (inl<chunk) chunk=inl; 157142425Snectar } 158238405Sjkim 159142425Snectar return 1; 160142425Snectar } 161142425Snectar 162142425Snectarstatic int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 163238405Sjkim const unsigned char *in, size_t inl) 164142425Snectar { 165238405Sjkim while (inl>=EVP_MAXCHUNK) 166238405Sjkim { 167238405Sjkim DES_cfb_encrypt(in,out,8,(long)EVP_MAXCHUNK,ctx->cipher_data, 168238405Sjkim (DES_cblock *)ctx->iv,ctx->encrypt); 169238405Sjkim inl-=EVP_MAXCHUNK; 170238405Sjkim in +=EVP_MAXCHUNK; 171238405Sjkim out+=EVP_MAXCHUNK; 172238405Sjkim } 173238405Sjkim if (inl) 174238405Sjkim DES_cfb_encrypt(in,out,8,(long)inl,ctx->cipher_data, 175238405Sjkim (DES_cblock *)ctx->iv,ctx->encrypt); 176142425Snectar return 1; 177142425Snectar } 178142425Snectar 179109998SmarkmBLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, 180238405Sjkim EVP_CIPH_RAND_KEY, des_init_key, NULL, 18168651Skris EVP_CIPHER_set_asn1_iv, 18268651Skris EVP_CIPHER_get_asn1_iv, 183160814Ssimon des_ctrl) 18468651Skris 185160814SsimonBLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1, 186238405Sjkim EVP_CIPH_RAND_KEY, des_init_key,NULL, 187142425Snectar EVP_CIPHER_set_asn1_iv, 188160814Ssimon EVP_CIPHER_get_asn1_iv,des_ctrl) 18968651Skris 190160814SsimonBLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8, 191238405Sjkim EVP_CIPH_RAND_KEY,des_init_key,NULL, 192142425Snectar EVP_CIPHER_set_asn1_iv, 193160814Ssimon EVP_CIPHER_get_asn1_iv,des_ctrl) 194142425Snectar 19568651Skrisstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 19668651Skris const unsigned char *iv, int enc) 19768651Skris { 198109998Smarkm DES_cblock *deskey = (DES_cblock *)key; 199160814Ssimon#ifdef EVP_CHECK_DES_KEY 200160814Ssimon if(DES_set_key_checked(deskey,ctx->cipher_data) != 0) 201160814Ssimon return 0; 202160814Ssimon#else 203109998Smarkm DES_set_key_unchecked(deskey,ctx->cipher_data); 204160814Ssimon#endif 20568651Skris return 1; 20668651Skris } 20768651Skris 208160814Ssimonstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 209160814Ssimon { 210160814Ssimon 211160814Ssimon switch(type) 212160814Ssimon { 213160814Ssimon case EVP_CTRL_RAND_KEY: 214160814Ssimon if (RAND_bytes(ptr, 8) <= 0) 215160814Ssimon return 0; 216160814Ssimon DES_set_odd_parity((DES_cblock *)ptr); 217160814Ssimon return 1; 218160814Ssimon 219160814Ssimon default: 220160814Ssimon return -1; 221160814Ssimon } 222160814Ssimon } 223160814Ssimon 22468651Skris#endif 225