des_enc.c revision 55714
155714Skris/* crypto/des/des_enc.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include "des_locl.h" 6055714Skris 6155714Skrisvoid des_encrypt(DES_LONG *data, des_key_schedule ks, int enc) 6255714Skris { 6355714Skris register DES_LONG l,r,t,u; 6455714Skris#ifdef DES_PTR 6555714Skris register const unsigned char *des_SP=(const unsigned char *)des_SPtrans; 6655714Skris#endif 6755714Skris#ifndef DES_UNROLL 6855714Skris register int i; 6955714Skris#endif 7055714Skris register DES_LONG *s; 7155714Skris 7255714Skris r=data[0]; 7355714Skris l=data[1]; 7455714Skris 7555714Skris IP(r,l); 7655714Skris /* Things have been modified so that the initial rotate is 7755714Skris * done outside the loop. This required the 7855714Skris * des_SPtrans values in sp.h to be rotated 1 bit to the right. 7955714Skris * One perl script later and things have a 5% speed up on a sparc2. 8055714Skris * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> 8155714Skris * for pointing this out. */ 8255714Skris /* clear the top bits on machines with 8byte longs */ 8355714Skris /* shift left by 2 */ 8455714Skris r=ROTATE(r,29)&0xffffffffL; 8555714Skris l=ROTATE(l,29)&0xffffffffL; 8655714Skris 8755714Skris s=ks->ks.deslong; 8855714Skris /* I don't know if it is worth the effort of loop unrolling the 8955714Skris * inner loop */ 9055714Skris if (enc) 9155714Skris { 9255714Skris#ifdef DES_UNROLL 9355714Skris D_ENCRYPT(l,r, 0); /* 1 */ 9455714Skris D_ENCRYPT(r,l, 2); /* 2 */ 9555714Skris D_ENCRYPT(l,r, 4); /* 3 */ 9655714Skris D_ENCRYPT(r,l, 6); /* 4 */ 9755714Skris D_ENCRYPT(l,r, 8); /* 5 */ 9855714Skris D_ENCRYPT(r,l,10); /* 6 */ 9955714Skris D_ENCRYPT(l,r,12); /* 7 */ 10055714Skris D_ENCRYPT(r,l,14); /* 8 */ 10155714Skris D_ENCRYPT(l,r,16); /* 9 */ 10255714Skris D_ENCRYPT(r,l,18); /* 10 */ 10355714Skris D_ENCRYPT(l,r,20); /* 11 */ 10455714Skris D_ENCRYPT(r,l,22); /* 12 */ 10555714Skris D_ENCRYPT(l,r,24); /* 13 */ 10655714Skris D_ENCRYPT(r,l,26); /* 14 */ 10755714Skris D_ENCRYPT(l,r,28); /* 15 */ 10855714Skris D_ENCRYPT(r,l,30); /* 16 */ 10955714Skris#else 11055714Skris for (i=0; i<32; i+=8) 11155714Skris { 11255714Skris D_ENCRYPT(l,r,i+0); /* 1 */ 11355714Skris D_ENCRYPT(r,l,i+2); /* 2 */ 11455714Skris D_ENCRYPT(l,r,i+4); /* 3 */ 11555714Skris D_ENCRYPT(r,l,i+6); /* 4 */ 11655714Skris } 11755714Skris#endif 11855714Skris } 11955714Skris else 12055714Skris { 12155714Skris#ifdef DES_UNROLL 12255714Skris D_ENCRYPT(l,r,30); /* 16 */ 12355714Skris D_ENCRYPT(r,l,28); /* 15 */ 12455714Skris D_ENCRYPT(l,r,26); /* 14 */ 12555714Skris D_ENCRYPT(r,l,24); /* 13 */ 12655714Skris D_ENCRYPT(l,r,22); /* 12 */ 12755714Skris D_ENCRYPT(r,l,20); /* 11 */ 12855714Skris D_ENCRYPT(l,r,18); /* 10 */ 12955714Skris D_ENCRYPT(r,l,16); /* 9 */ 13055714Skris D_ENCRYPT(l,r,14); /* 8 */ 13155714Skris D_ENCRYPT(r,l,12); /* 7 */ 13255714Skris D_ENCRYPT(l,r,10); /* 6 */ 13355714Skris D_ENCRYPT(r,l, 8); /* 5 */ 13455714Skris D_ENCRYPT(l,r, 6); /* 4 */ 13555714Skris D_ENCRYPT(r,l, 4); /* 3 */ 13655714Skris D_ENCRYPT(l,r, 2); /* 2 */ 13755714Skris D_ENCRYPT(r,l, 0); /* 1 */ 13855714Skris#else 13955714Skris for (i=30; i>0; i-=8) 14055714Skris { 14155714Skris D_ENCRYPT(l,r,i-0); /* 16 */ 14255714Skris D_ENCRYPT(r,l,i-2); /* 15 */ 14355714Skris D_ENCRYPT(l,r,i-4); /* 14 */ 14455714Skris D_ENCRYPT(r,l,i-6); /* 13 */ 14555714Skris } 14655714Skris#endif 14755714Skris } 14855714Skris 14955714Skris /* rotate and clear the top bits on machines with 8byte longs */ 15055714Skris l=ROTATE(l,3)&0xffffffffL; 15155714Skris r=ROTATE(r,3)&0xffffffffL; 15255714Skris 15355714Skris FP(r,l); 15455714Skris data[0]=l; 15555714Skris data[1]=r; 15655714Skris l=r=t=u=0; 15755714Skris } 15855714Skris 15955714Skrisvoid des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) 16055714Skris { 16155714Skris register DES_LONG l,r,t,u; 16255714Skris#ifdef DES_PTR 16355714Skris register const unsigned char *des_SP=(const unsigned char *)des_SPtrans; 16455714Skris#endif 16555714Skris#ifndef DES_UNROLL 16655714Skris register int i; 16755714Skris#endif 16855714Skris register DES_LONG *s; 16955714Skris 17055714Skris r=data[0]; 17155714Skris l=data[1]; 17255714Skris 17355714Skris /* Things have been modified so that the initial rotate is 17455714Skris * done outside the loop. This required the 17555714Skris * des_SPtrans values in sp.h to be rotated 1 bit to the right. 17655714Skris * One perl script later and things have a 5% speed up on a sparc2. 17755714Skris * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> 17855714Skris * for pointing this out. */ 17955714Skris /* clear the top bits on machines with 8byte longs */ 18055714Skris r=ROTATE(r,29)&0xffffffffL; 18155714Skris l=ROTATE(l,29)&0xffffffffL; 18255714Skris 18355714Skris s=ks->ks.deslong; 18455714Skris /* I don't know if it is worth the effort of loop unrolling the 18555714Skris * inner loop */ 18655714Skris if (enc) 18755714Skris { 18855714Skris#ifdef DES_UNROLL 18955714Skris D_ENCRYPT(l,r, 0); /* 1 */ 19055714Skris D_ENCRYPT(r,l, 2); /* 2 */ 19155714Skris D_ENCRYPT(l,r, 4); /* 3 */ 19255714Skris D_ENCRYPT(r,l, 6); /* 4 */ 19355714Skris D_ENCRYPT(l,r, 8); /* 5 */ 19455714Skris D_ENCRYPT(r,l,10); /* 6 */ 19555714Skris D_ENCRYPT(l,r,12); /* 7 */ 19655714Skris D_ENCRYPT(r,l,14); /* 8 */ 19755714Skris D_ENCRYPT(l,r,16); /* 9 */ 19855714Skris D_ENCRYPT(r,l,18); /* 10 */ 19955714Skris D_ENCRYPT(l,r,20); /* 11 */ 20055714Skris D_ENCRYPT(r,l,22); /* 12 */ 20155714Skris D_ENCRYPT(l,r,24); /* 13 */ 20255714Skris D_ENCRYPT(r,l,26); /* 14 */ 20355714Skris D_ENCRYPT(l,r,28); /* 15 */ 20455714Skris D_ENCRYPT(r,l,30); /* 16 */ 20555714Skris#else 20655714Skris for (i=0; i<32; i+=8) 20755714Skris { 20855714Skris D_ENCRYPT(l,r,i+0); /* 1 */ 20955714Skris D_ENCRYPT(r,l,i+2); /* 2 */ 21055714Skris D_ENCRYPT(l,r,i+4); /* 3 */ 21155714Skris D_ENCRYPT(r,l,i+6); /* 4 */ 21255714Skris } 21355714Skris#endif 21455714Skris } 21555714Skris else 21655714Skris { 21755714Skris#ifdef DES_UNROLL 21855714Skris D_ENCRYPT(l,r,30); /* 16 */ 21955714Skris D_ENCRYPT(r,l,28); /* 15 */ 22055714Skris D_ENCRYPT(l,r,26); /* 14 */ 22155714Skris D_ENCRYPT(r,l,24); /* 13 */ 22255714Skris D_ENCRYPT(l,r,22); /* 12 */ 22355714Skris D_ENCRYPT(r,l,20); /* 11 */ 22455714Skris D_ENCRYPT(l,r,18); /* 10 */ 22555714Skris D_ENCRYPT(r,l,16); /* 9 */ 22655714Skris D_ENCRYPT(l,r,14); /* 8 */ 22755714Skris D_ENCRYPT(r,l,12); /* 7 */ 22855714Skris D_ENCRYPT(l,r,10); /* 6 */ 22955714Skris D_ENCRYPT(r,l, 8); /* 5 */ 23055714Skris D_ENCRYPT(l,r, 6); /* 4 */ 23155714Skris D_ENCRYPT(r,l, 4); /* 3 */ 23255714Skris D_ENCRYPT(l,r, 2); /* 2 */ 23355714Skris D_ENCRYPT(r,l, 0); /* 1 */ 23455714Skris#else 23555714Skris for (i=30; i>0; i-=8) 23655714Skris { 23755714Skris D_ENCRYPT(l,r,i-0); /* 16 */ 23855714Skris D_ENCRYPT(r,l,i-2); /* 15 */ 23955714Skris D_ENCRYPT(l,r,i-4); /* 14 */ 24055714Skris D_ENCRYPT(r,l,i-6); /* 13 */ 24155714Skris } 24255714Skris#endif 24355714Skris } 24455714Skris /* rotate and clear the top bits on machines with 8byte longs */ 24555714Skris data[0]=ROTATE(l,3)&0xffffffffL; 24655714Skris data[1]=ROTATE(r,3)&0xffffffffL; 24755714Skris l=r=t=u=0; 24855714Skris } 24955714Skris 25055714Skrisvoid des_encrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, 25155714Skris des_key_schedule ks3) 25255714Skris { 25355714Skris register DES_LONG l,r; 25455714Skris 25555714Skris l=data[0]; 25655714Skris r=data[1]; 25755714Skris IP(l,r); 25855714Skris data[0]=l; 25955714Skris data[1]=r; 26055714Skris des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT); 26155714Skris des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT); 26255714Skris des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT); 26355714Skris l=data[0]; 26455714Skris r=data[1]; 26555714Skris FP(r,l); 26655714Skris data[0]=l; 26755714Skris data[1]=r; 26855714Skris } 26955714Skris 27055714Skrisvoid des_decrypt3(DES_LONG *data, des_key_schedule ks1, des_key_schedule ks2, 27155714Skris des_key_schedule ks3) 27255714Skris { 27355714Skris register DES_LONG l,r; 27455714Skris 27555714Skris l=data[0]; 27655714Skris r=data[1]; 27755714Skris IP(l,r); 27855714Skris data[0]=l; 27955714Skris data[1]=r; 28055714Skris des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT); 28155714Skris des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT); 28255714Skris des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT); 28355714Skris l=data[0]; 28455714Skris r=data[1]; 28555714Skris FP(r,l); 28655714Skris data[0]=l; 28755714Skris data[1]=r; 28855714Skris } 28955714Skris 29055714Skris#ifndef DES_DEFAULT_OPTIONS 29155714Skris 29255714Skris#undef CBC_ENC_C__DONT_UPDATE_IV 29355714Skris#include "ncbc_enc.c" /* des_ncbc_encrypt */ 29455714Skris 29555714Skrisvoid des_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, 29655714Skris long length, des_key_schedule ks1, des_key_schedule ks2, 29755714Skris des_key_schedule ks3, des_cblock *ivec, int enc) 29855714Skris { 29955714Skris register DES_LONG tin0,tin1; 30055714Skris register DES_LONG tout0,tout1,xor0,xor1; 30155714Skris register const unsigned char *in; 30255714Skris unsigned char *out; 30355714Skris register long l=length; 30455714Skris DES_LONG tin[2]; 30555714Skris unsigned char *iv; 30655714Skris 30755714Skris in=input; 30855714Skris out=output; 30955714Skris iv = &(*ivec)[0]; 31055714Skris 31155714Skris if (enc) 31255714Skris { 31355714Skris c2l(iv,tout0); 31455714Skris c2l(iv,tout1); 31555714Skris for (l-=8; l>=0; l-=8) 31655714Skris { 31755714Skris c2l(in,tin0); 31855714Skris c2l(in,tin1); 31955714Skris tin0^=tout0; 32055714Skris tin1^=tout1; 32155714Skris 32255714Skris tin[0]=tin0; 32355714Skris tin[1]=tin1; 32455714Skris des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); 32555714Skris tout0=tin[0]; 32655714Skris tout1=tin[1]; 32755714Skris 32855714Skris l2c(tout0,out); 32955714Skris l2c(tout1,out); 33055714Skris } 33155714Skris if (l != -8) 33255714Skris { 33355714Skris c2ln(in,tin0,tin1,l+8); 33455714Skris tin0^=tout0; 33555714Skris tin1^=tout1; 33655714Skris 33755714Skris tin[0]=tin0; 33855714Skris tin[1]=tin1; 33955714Skris des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); 34055714Skris tout0=tin[0]; 34155714Skris tout1=tin[1]; 34255714Skris 34355714Skris l2c(tout0,out); 34455714Skris l2c(tout1,out); 34555714Skris } 34655714Skris iv = &(*ivec)[0]; 34755714Skris l2c(tout0,iv); 34855714Skris l2c(tout1,iv); 34955714Skris } 35055714Skris else 35155714Skris { 35255714Skris register DES_LONG t0,t1; 35355714Skris 35455714Skris c2l(iv,xor0); 35555714Skris c2l(iv,xor1); 35655714Skris for (l-=8; l>=0; l-=8) 35755714Skris { 35855714Skris c2l(in,tin0); 35955714Skris c2l(in,tin1); 36055714Skris 36155714Skris t0=tin0; 36255714Skris t1=tin1; 36355714Skris 36455714Skris tin[0]=tin0; 36555714Skris tin[1]=tin1; 36655714Skris des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); 36755714Skris tout0=tin[0]; 36855714Skris tout1=tin[1]; 36955714Skris 37055714Skris tout0^=xor0; 37155714Skris tout1^=xor1; 37255714Skris l2c(tout0,out); 37355714Skris l2c(tout1,out); 37455714Skris xor0=t0; 37555714Skris xor1=t1; 37655714Skris } 37755714Skris if (l != -8) 37855714Skris { 37955714Skris c2l(in,tin0); 38055714Skris c2l(in,tin1); 38155714Skris 38255714Skris t0=tin0; 38355714Skris t1=tin1; 38455714Skris 38555714Skris tin[0]=tin0; 38655714Skris tin[1]=tin1; 38755714Skris des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); 38855714Skris tout0=tin[0]; 38955714Skris tout1=tin[1]; 39055714Skris 39155714Skris tout0^=xor0; 39255714Skris tout1^=xor1; 39355714Skris l2cn(tout0,tout1,out,l+8); 39455714Skris xor0=t0; 39555714Skris xor1=t1; 39655714Skris } 39755714Skris 39855714Skris iv = &(*ivec)[0]; 39955714Skris l2c(xor0,iv); 40055714Skris l2c(xor1,iv); 40155714Skris } 40255714Skris tin0=tin1=tout0=tout1=xor0=xor1=0; 40355714Skris tin[0]=tin[1]=0; 40455714Skris } 40555714Skris 40655714Skris#endif /* DES_DEFAULT_OPTIONS */ 407