e_des.c revision 296279
11590Srgrimes/* crypto/evp/e_des.c */ 21590Srgrimes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 31590Srgrimes * All rights reserved. 41590Srgrimes * 51590Srgrimes * This package is an SSL implementation written 61590Srgrimes * by Eric Young (eay@cryptsoft.com). 71590Srgrimes * The implementation was written so as to conform with Netscapes SSL. 81590Srgrimes * 91590Srgrimes * This library is free for commercial and non-commercial use as long as 101590Srgrimes * the following conditions are aheared to. The following conditions 111590Srgrimes * apply to all code found in this distribution, be it the RC4, RSA, 121590Srgrimes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 131590Srgrimes * included with this distribution is covered by the same copyright terms 141590Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 151590Srgrimes * 161590Srgrimes * Copyright remains Eric Young's, and as such any Copyright notices in 171590Srgrimes * the code are not to be removed. 181590Srgrimes * If this package is used in a product, Eric Young should be given attribution 191590Srgrimes * as the author of the parts of the library used. 201590Srgrimes * This can be in the form of a textual message at program startup or 211590Srgrimes * in documentation (online or textual) provided with the package. 221590Srgrimes * 231590Srgrimes * Redistribution and use in source and binary forms, with or without 241590Srgrimes * modification, are permitted provided that the following conditions 251590Srgrimes * are met: 261590Srgrimes * 1. Redistributions of source code must retain the copyright 271590Srgrimes * notice, this list of conditions and the following disclaimer. 281590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 291590Srgrimes * notice, this list of conditions and the following disclaimer in the 301590Srgrimes * documentation and/or other materials provided with the distribution. 311590Srgrimes * 3. All advertising materials mentioning features or use of this software 3226921Scharnier * must display the following acknowledgement: 3350477Speter * "This product includes cryptographic software written by 341590Srgrimes * Eric Young (eay@cryptsoft.com)" 351590Srgrimes * The word 'cryptographic' can be left out if the rouines from the library 361590Srgrimes * being used are not cryptographic related :-). 3741568Sarchie * 4. If you include any Windows specific code (or a derivative thereof) from 381590Srgrimes * the apps directory (application code) you must include an acknowledgement: 391590Srgrimes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 401590Srgrimes * 411590Srgrimes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 421590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 431590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 441590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 451590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 461590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 471590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 491590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 501590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 511590Srgrimes * SUCH DAMAGE. 521590Srgrimes * 531590Srgrimes * The licence and distribution terms for any publically available version or 541590Srgrimes * derivative of this code cannot be changed. i.e. this code cannot simply be 551590Srgrimes * copied and put under another distribution licence 561590Srgrimes * [including the GNU Public Licence.] 5710050Swpaul */ 5810050Swpaul 5910050Swpaul#include <stdio.h> 601590Srgrimes#include "cryptlib.h" 611590Srgrimes#ifndef OPENSSL_NO_DES 621590Srgrimes# include <openssl/evp.h> 631590Srgrimes# include <openssl/objects.h> 641590Srgrimes# include "evp_locl.h" 651590Srgrimes# include <openssl/des.h> 661590Srgrimes# include <openssl/rand.h> 671590Srgrimes 681590Srgrimestypedef struct { 691590Srgrimes union { 701590Srgrimes double align; 711590Srgrimes DES_key_schedule ks; 721590Srgrimes } ks; 731590Srgrimes union { 741590Srgrimes void (*cbc) (const void *, void *, size_t, 751590Srgrimes const DES_key_schedule *, unsigned char *); 761590Srgrimes } stream; 771590Srgrimes} EVP_DES_KEY; 781590Srgrimes 791590Srgrimes# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) 801590Srgrimes/* ----------^^^ this is not a typo, just a way to detect that 811590Srgrimes * assembler support was in general requested... */ 821590Srgrimes# include "sparc_arch.h" 831590Srgrimes 841590Srgrimesextern unsigned int OPENSSL_sparcv9cap_P[]; 851590Srgrimes 861590Srgrimes# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) 871590Srgrimes 881590Srgrimesvoid des_t4_key_expand(const void *key, DES_key_schedule *ks); 891590Srgrimesvoid des_t4_cbc_encrypt(const void *inp, void *out, size_t len, 901590Srgrimes const DES_key_schedule *ks, unsigned char iv[8]); 911590Srgrimesvoid des_t4_cbc_decrypt(const void *inp, void *out, size_t len, 921590Srgrimes const DES_key_schedule *ks, unsigned char iv[8]); 931590Srgrimes# endif 941590Srgrimes 951590Srgrimesstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 961590Srgrimes const unsigned char *iv, int enc); 971590Srgrimesstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); 981590Srgrimes 991590Srgrimes/* 1001590Srgrimes * Because of various casts and different names can't use 1011590Srgrimes * IMPLEMENT_BLOCK_CIPHER 10210050Swpaul */ 10310050Swpaul 10414212Swpaulstatic int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 10510050Swpaul const unsigned char *in, size_t inl) 10616388Swpaul{ 1071590Srgrimes BLOCK_CIPHER_ecb_loop() 10810050Swpaul DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), 1091590Srgrimes ctx->cipher_data, ctx->encrypt); 1101590Srgrimes return 1; 1111590Srgrimes} 1121590Srgrimes 1131590Srgrimesstatic int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1141590Srgrimes const unsigned char *in, size_t inl) 1151590Srgrimes{ 1161590Srgrimes while (inl >= EVP_MAXCHUNK) { 1171590Srgrimes DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 1181590Srgrimes (DES_cblock *)ctx->iv, &ctx->num); 1191590Srgrimes inl -= EVP_MAXCHUNK; 1201590Srgrimes in += EVP_MAXCHUNK; 1211590Srgrimes out += EVP_MAXCHUNK; 1221590Srgrimes } 12346081Simp if (inl) 1241590Srgrimes DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, 1251590Srgrimes (DES_cblock *)ctx->iv, &ctx->num); 1261590Srgrimes return 1; 1271590Srgrimes} 1281590Srgrimes 12914212Swpaulstatic int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 13014212Swpaul const unsigned char *in, size_t inl) 13114212Swpaul{ 13214212Swpaul EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; 13314212Swpaul 13414212Swpaul if (dat->stream.cbc != NULL) { 13514212Swpaul (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); 1361590Srgrimes return 1; 1371590Srgrimes } 1381590Srgrimes while (inl >= EVP_MAXCHUNK) { 1396269Sjkh DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 1401590Srgrimes (DES_cblock *)ctx->iv, ctx->encrypt); 1416269Sjkh inl -= EVP_MAXCHUNK; 1421590Srgrimes in += EVP_MAXCHUNK; 14354968Simp out += EVP_MAXCHUNK; 14454968Simp } 1457220Sache if (inl) 14654968Simp DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, 1478874Srgrimes (DES_cblock *)ctx->iv, ctx->encrypt); 1486269Sjkh return 1; 14954968Simp} 15054968Simp 1517220Sachestatic int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 15254968Simp const unsigned char *in, size_t inl) 1538874Srgrimes{ 1546269Sjkh while (inl >= EVP_MAXCHUNK) { 15554968Simp DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, 15654968Simp (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 1577220Sache inl -= EVP_MAXCHUNK; 15854968Simp in += EVP_MAXCHUNK; 1598874Srgrimes out += EVP_MAXCHUNK; 1606269Sjkh } 16154968Simp if (inl) 16254968Simp DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, 1637220Sache (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); 16454968Simp return 1; 1651590Srgrimes} 16654968Simp 16754968Simp/* 16838307Sthepish * Although we have a CFB-r implementation for DES, it doesn't pack the right 16954968Simp * way, so wrap it here 17038307Sthepish */ 1711590Srgrimesstatic int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 1721590Srgrimes const unsigned char *in, size_t inl) 1731590Srgrimes{ 1741590Srgrimes size_t n, chunk = EVP_MAXCHUNK / 8; 1751590Srgrimes unsigned char c[1], d[1]; 1761590Srgrimes 1771590Srgrimes if (inl < chunk) 1781590Srgrimes chunk = inl; 1791590Srgrimes 1801590Srgrimes while (inl && inl >= chunk) { 1811590Srgrimes for (n = 0; n < chunk * 8; ++n) { 1821590Srgrimes c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; 18326921Scharnier DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, 18419783Speter (DES_cblock *)ctx->iv, ctx->encrypt); 1851590Srgrimes out[n / 8] = 1861590Srgrimes (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | 1871590Srgrimes ((d[0] & 0x80) >> (unsigned int)(n % 8)); 1881590Srgrimes } 1891590Srgrimes inl -= chunk; 1901590Srgrimes in += chunk; 1911590Srgrimes out += chunk; 1921590Srgrimes if (inl < chunk) 1931590Srgrimes chunk = inl; 19426921Scharnier } 1951590Srgrimes 19626921Scharnier return 1; 1971590Srgrimes} 1981590Srgrimes 1991590Srgrimesstatic int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 20026921Scharnier const unsigned char *in, size_t inl) 2011590Srgrimes{ 2021590Srgrimes while (inl >= EVP_MAXCHUNK) { 2031590Srgrimes DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data, 2041590Srgrimes (DES_cblock *)ctx->iv, ctx->encrypt); 2051590Srgrimes inl -= EVP_MAXCHUNK; 20626921Scharnier in += EVP_MAXCHUNK; 2071590Srgrimes out += EVP_MAXCHUNK; 2081590Srgrimes } 2091590Srgrimes if (inl) 2101590Srgrimes DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, 2111590Srgrimes (DES_cblock *)ctx->iv, ctx->encrypt); 2121590Srgrimes return 1; 2131590Srgrimes} 2141590Srgrimes 2151590SrgrimesBLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64, 2161590Srgrimes EVP_CIPH_RAND_KEY, des_init_key, NULL, 21726921Scharnier EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 2181590Srgrimes 2191590Srgrimes BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1, 2201590Srgrimes EVP_CIPH_RAND_KEY, des_init_key, NULL, 2211590Srgrimes EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 2221590Srgrimes 2231590Srgrimes BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8, 2241590Srgrimes EVP_CIPH_RAND_KEY, des_init_key, NULL, 2251590Srgrimes EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) 2261590Srgrimes 2271590Srgrimesstatic int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 2281590Srgrimes const unsigned char *iv, int enc) 2291590Srgrimes{ 2301590Srgrimes DES_cblock *deskey = (DES_cblock *)key; 2311590Srgrimes EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; 2321590Srgrimes 2331590Srgrimes dat->stream.cbc = NULL; 2341590Srgrimes# if defined(SPARC_DES_CAPABLE) 2351590Srgrimes if (SPARC_DES_CAPABLE) { 2361590Srgrimes int mode = ctx->cipher->flags & EVP_CIPH_MODE; 2371590Srgrimes 2381590Srgrimes if (mode == EVP_CIPH_CBC_MODE) { 23938307Sthepish des_t4_key_expand(key, &dat->ks.ks); 24054968Simp dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt; 2411590Srgrimes return 1; 2421590Srgrimes } 24338307Sthepish } 24438307Sthepish# endif 24538307Sthepish# ifdef EVP_CHECK_DES_KEY 2461590Srgrimes if (DES_set_key_checked(deskey, dat->ks.ks) != 0) 24717544Speter return 0; 24817544Speter# else 24917544Speter DES_set_key_unchecked(deskey, ctx->cipher_data); 2501590Srgrimes# endif 2511590Srgrimes return 1; 2521590Srgrimes} 2531590Srgrimes 2541590Srgrimesstatic int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 2551590Srgrimes{ 25626921Scharnier 2571590Srgrimes switch (type) { 2581590Srgrimes case EVP_CTRL_RAND_KEY: 25926921Scharnier if (RAND_bytes(ptr, 8) <= 0) 2601590Srgrimes return 0; 2611590Srgrimes DES_set_odd_parity((DES_cblock *)ptr); 262 return 1; 263 264 default: 265 return -1; 266 } 267} 268 269#endif 270