1*48d3e433Sjsing /* $OpenBSD: des_local.h,v 1.5 2024/08/31 16:22:18 jsing Exp $ */ 2c9675a23Stb /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) 3c9675a23Stb * All rights reserved. 4c9675a23Stb * 5c9675a23Stb * This package is an SSL implementation written 6c9675a23Stb * by Eric Young (eay@cryptsoft.com). 7c9675a23Stb * The implementation was written so as to conform with Netscapes SSL. 8c9675a23Stb * 9c9675a23Stb * This library is free for commercial and non-commercial use as long as 10c9675a23Stb * the following conditions are aheared to. The following conditions 11c9675a23Stb * apply to all code found in this distribution, be it the RC4, RSA, 12c9675a23Stb * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13c9675a23Stb * included with this distribution is covered by the same copyright terms 14c9675a23Stb * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15c9675a23Stb * 16c9675a23Stb * Copyright remains Eric Young's, and as such any Copyright notices in 17c9675a23Stb * the code are not to be removed. 18c9675a23Stb * If this package is used in a product, Eric Young should be given attribution 19c9675a23Stb * as the author of the parts of the library used. 20c9675a23Stb * This can be in the form of a textual message at program startup or 21c9675a23Stb * in documentation (online or textual) provided with the package. 22c9675a23Stb * 23c9675a23Stb * Redistribution and use in source and binary forms, with or without 24c9675a23Stb * modification, are permitted provided that the following conditions 25c9675a23Stb * are met: 26c9675a23Stb * 1. Redistributions of source code must retain the copyright 27c9675a23Stb * notice, this list of conditions and the following disclaimer. 28c9675a23Stb * 2. Redistributions in binary form must reproduce the above copyright 29c9675a23Stb * notice, this list of conditions and the following disclaimer in the 30c9675a23Stb * documentation and/or other materials provided with the distribution. 31c9675a23Stb * 3. All advertising materials mentioning features or use of this software 32c9675a23Stb * must display the following acknowledgement: 33c9675a23Stb * "This product includes cryptographic software written by 34c9675a23Stb * Eric Young (eay@cryptsoft.com)" 35c9675a23Stb * The word 'cryptographic' can be left out if the rouines from the library 36c9675a23Stb * being used are not cryptographic related :-). 37c9675a23Stb * 4. If you include any Windows specific code (or a derivative thereof) from 38c9675a23Stb * the apps directory (application code) you must include an acknowledgement: 39c9675a23Stb * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40c9675a23Stb * 41c9675a23Stb * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42c9675a23Stb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43c9675a23Stb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44c9675a23Stb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45c9675a23Stb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46c9675a23Stb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47c9675a23Stb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48c9675a23Stb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49c9675a23Stb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50c9675a23Stb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51c9675a23Stb * SUCH DAMAGE. 52c9675a23Stb * 53c9675a23Stb * The licence and distribution terms for any publically available version or 54c9675a23Stb * derivative of this code cannot be changed. i.e. this code cannot simply be 55c9675a23Stb * copied and put under another distribution licence 56c9675a23Stb * [including the GNU Public Licence.] 57c9675a23Stb */ 58c9675a23Stb 59c9675a23Stb #ifndef HEADER_DES_LOCL_H 60c9675a23Stb #define HEADER_DES_LOCL_H 61c9675a23Stb 62c9675a23Stb #include <math.h> 63c9675a23Stb #include <stdint.h> 64c9675a23Stb #include <stdio.h> 65c9675a23Stb #include <stdlib.h> 66c9675a23Stb #include <string.h> 67c9675a23Stb #include <unistd.h> 68c9675a23Stb 69c9675a23Stb #include <openssl/opensslconf.h> 70c9675a23Stb 71c9675a23Stb #include <openssl/des.h> 72c9675a23Stb 73c9675a23Stb __BEGIN_HIDDEN_DECLS 74c9675a23Stb 75c9675a23Stb #define ITERATIONS 16 76c9675a23Stb 77c9675a23Stb #define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 78c9675a23Stb l|=((DES_LONG)(*((c)++)))<< 8L, \ 79c9675a23Stb l|=((DES_LONG)(*((c)++)))<<16L, \ 80c9675a23Stb l|=((DES_LONG)(*((c)++)))<<24L) 81c9675a23Stb 82c9675a23Stb /* NOTE - c is not incremented as per c2l */ 83c9675a23Stb #define c2ln(c,l1,l2,n) { \ 84c9675a23Stb c+=n; \ 85c9675a23Stb l1=l2=0; \ 86c9675a23Stb switch (n) { \ 87c9675a23Stb case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ 88c9675a23Stb case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ 89c9675a23Stb case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ 90c9675a23Stb case 5: l2|=((DES_LONG)(*(--(c)))); \ 91c9675a23Stb case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ 92c9675a23Stb case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ 93c9675a23Stb case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ 94c9675a23Stb case 1: l1|=((DES_LONG)(*(--(c)))); \ 95c9675a23Stb } \ 96c9675a23Stb } 97c9675a23Stb 98c9675a23Stb #define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 99c9675a23Stb *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 100c9675a23Stb *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 101c9675a23Stb *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 102c9675a23Stb 103c9675a23Stb /* NOTE - c is not incremented as per l2c */ 104c9675a23Stb #define l2cn(l1,l2,c,n) { \ 105c9675a23Stb c+=n; \ 106c9675a23Stb switch (n) { \ 107c9675a23Stb case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff);\ 108c9675a23Stb case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff);\ 109c9675a23Stb case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff);\ 110c9675a23Stb case 5: *(--(c))=(unsigned char)(((l2) )&0xff);\ 111c9675a23Stb case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff);\ 112c9675a23Stb case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff);\ 113c9675a23Stb case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff);\ 114c9675a23Stb case 1: *(--(c))=(unsigned char)(((l1) )&0xff);\ 115c9675a23Stb } \ 116c9675a23Stb } 117c9675a23Stb 118aad5d5cdSbeck static inline uint32_t 119aad5d5cdSbeck ROTATE(uint32_t a, uint32_t n) 120c9675a23Stb { 121c9675a23Stb return (a >> n) + (a << (32 - n)); 122c9675a23Stb } 123c9675a23Stb 124c9675a23Stb /* Don't worry about the LOAD_DATA() stuff, that is used by 125c9675a23Stb * fcrypt() to add it's little bit to the front */ 126c9675a23Stb 127c9675a23Stb #ifdef DES_FCRYPT 128c9675a23Stb 129c9675a23Stb #define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ 130c9675a23Stb { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } 131c9675a23Stb 132c9675a23Stb #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ 133c9675a23Stb t=R^(R>>16L); \ 134c9675a23Stb u=t&E0; t&=E1; \ 135c9675a23Stb tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ 136c9675a23Stb tmp=(t<<16); t^=R^s[S+1]; t^=tmp 137c9675a23Stb #else 138c9675a23Stb #define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) 139c9675a23Stb #define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ 140c9675a23Stb u=R^s[S ]; \ 141c9675a23Stb t=R^s[S+1] 142c9675a23Stb #endif 143c9675a23Stb 144c9675a23Stb #define D_ENCRYPT(LL,R,S) { \ 145c9675a23Stb LOAD_DATA_tmp(R,S,u,t,E0,E1); \ 146c9675a23Stb t=ROTATE(t,4); \ 147c9675a23Stb LL^= \ 148c9675a23Stb DES_SPtrans[0][(u>> 2L)&0x3f]^ \ 149c9675a23Stb DES_SPtrans[2][(u>>10L)&0x3f]^ \ 150c9675a23Stb DES_SPtrans[4][(u>>18L)&0x3f]^ \ 151c9675a23Stb DES_SPtrans[6][(u>>26L)&0x3f]^ \ 152c9675a23Stb DES_SPtrans[1][(t>> 2L)&0x3f]^ \ 153c9675a23Stb DES_SPtrans[3][(t>>10L)&0x3f]^ \ 154c9675a23Stb DES_SPtrans[5][(t>>18L)&0x3f]^ \ 155c9675a23Stb DES_SPtrans[7][(t>>26L)&0x3f]; } 156c9675a23Stb 157c9675a23Stb /* IP and FP 158c9675a23Stb * The problem is more of a geometric problem that random bit fiddling. 159c9675a23Stb 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 160c9675a23Stb 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 161c9675a23Stb 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 162c9675a23Stb 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 163c9675a23Stb 164c9675a23Stb 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 165c9675a23Stb 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 166c9675a23Stb 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 167c9675a23Stb 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 168c9675a23Stb 169c9675a23Stb The output has been subject to swaps of the form 170c9675a23Stb 0 1 -> 3 1 but the odd and even bits have been put into 171c9675a23Stb 2 3 2 0 172c9675a23Stb different words. The main trick is to remember that 173c9675a23Stb t=((l>>size)^r)&(mask); 174c9675a23Stb r^=t; 175c9675a23Stb l^=(t<<size); 176c9675a23Stb can be used to swap and move bits between words. 177c9675a23Stb 178c9675a23Stb So l = 0 1 2 3 r = 16 17 18 19 179c9675a23Stb 4 5 6 7 20 21 22 23 180c9675a23Stb 8 9 10 11 24 25 26 27 181c9675a23Stb 12 13 14 15 28 29 30 31 182c9675a23Stb becomes (for size == 2 and mask == 0x3333) 183c9675a23Stb t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19 184c9675a23Stb 6^20 7^21 -- -- 4 5 20 21 6 7 22 23 185c9675a23Stb 10^24 11^25 -- -- 8 9 24 25 10 11 24 25 186c9675a23Stb 14^28 15^29 -- -- 12 13 28 29 14 15 28 29 187c9675a23Stb 188c9675a23Stb Thanks for hints from Richard Outerbridge - he told me IP&FP 189c9675a23Stb could be done in 15 xor, 10 shifts and 5 ands. 190c9675a23Stb When I finally started to think of the problem in 2D 191c9675a23Stb I first got ~42 operations without xors. When I remembered 192c9675a23Stb how to use xors :-) I got it to its final state. 193c9675a23Stb */ 194c9675a23Stb #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)), \ 195c9675a23Stb (b)^=(t), \ 196c9675a23Stb (a)^=((t)<<(n))) 197c9675a23Stb 198c9675a23Stb #define IP(l,r) \ 199c9675a23Stb { \ 200c9675a23Stb DES_LONG tt; \ 201c9675a23Stb PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ 202c9675a23Stb PERM_OP(l,r,tt,16,0x0000ffffL); \ 203c9675a23Stb PERM_OP(r,l,tt, 2,0x33333333L); \ 204c9675a23Stb PERM_OP(l,r,tt, 8,0x00ff00ffL); \ 205c9675a23Stb PERM_OP(r,l,tt, 1,0x55555555L); \ 206c9675a23Stb } 207c9675a23Stb 208c9675a23Stb #define FP(l,r) \ 209c9675a23Stb { \ 210c9675a23Stb DES_LONG tt; \ 211c9675a23Stb PERM_OP(l,r,tt, 1,0x55555555L); \ 212c9675a23Stb PERM_OP(r,l,tt, 8,0x00ff00ffL); \ 213c9675a23Stb PERM_OP(l,r,tt, 2,0x33333333L); \ 214c9675a23Stb PERM_OP(r,l,tt,16,0x0000ffffL); \ 215c9675a23Stb PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ 216c9675a23Stb } 217c9675a23Stb 218c9675a23Stb extern const DES_LONG DES_SPtrans[8][64]; 219c9675a23Stb 220c9675a23Stb #ifdef OPENSSL_SMALL_FOOTPRINT 221c9675a23Stb #undef DES_UNROLL 222c9675a23Stb #endif 223c9675a23Stb 224c9675a23Stb __END_HIDDEN_DECLS 225c9675a23Stb 226c9675a23Stb #endif 227