1*ebfedea0SLionel Sambuc /* $NetBSD: des.c,v 1.1.1.1 2011/04/13 18:14:49 elric Exp $ */ 2*ebfedea0SLionel Sambuc 3*ebfedea0SLionel Sambuc /* 4*ebfedea0SLionel Sambuc * Copyright (c) 2005 Kungliga Tekniska Högskolan 5*ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden). 6*ebfedea0SLionel Sambuc * All rights reserved. 7*ebfedea0SLionel Sambuc * 8*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 9*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 10*ebfedea0SLionel Sambuc * are met: 11*ebfedea0SLionel Sambuc * 12*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 13*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 14*ebfedea0SLionel Sambuc * 15*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 16*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 17*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution. 18*ebfedea0SLionel Sambuc * 19*ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors 20*ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software 21*ebfedea0SLionel Sambuc * without specific prior written permission. 22*ebfedea0SLionel Sambuc * 23*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24*ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26*ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27*ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28*ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29*ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30*ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31*ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32*ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33*ebfedea0SLionel Sambuc * SUCH DAMAGE. 34*ebfedea0SLionel Sambuc */ 35*ebfedea0SLionel Sambuc 36*ebfedea0SLionel Sambuc /** 37*ebfedea0SLionel Sambuc * @page page_des DES - Data Encryption Standard crypto interface 38*ebfedea0SLionel Sambuc * 39*ebfedea0SLionel Sambuc * See the library functions here: @ref hcrypto_des 40*ebfedea0SLionel Sambuc * 41*ebfedea0SLionel Sambuc * DES was created by IBM, modififed by NSA and then adopted by NBS 42*ebfedea0SLionel Sambuc * (now NIST) and published ad FIPS PUB 46 (updated by FIPS 46-1). 43*ebfedea0SLionel Sambuc * 44*ebfedea0SLionel Sambuc * Since the 19th May 2005 DES was withdrawn by NIST and should no 45*ebfedea0SLionel Sambuc * longer be used. See @ref page_evp for replacement encryption 46*ebfedea0SLionel Sambuc * algorithms and interfaces. 47*ebfedea0SLionel Sambuc * 48*ebfedea0SLionel Sambuc * Read more the iteresting history of DES on Wikipedia 49*ebfedea0SLionel Sambuc * http://www.wikipedia.org/wiki/Data_Encryption_Standard . 50*ebfedea0SLionel Sambuc * 51*ebfedea0SLionel Sambuc * @section des_keygen DES key generation 52*ebfedea0SLionel Sambuc * 53*ebfedea0SLionel Sambuc * To generate a DES key safely you have to use the code-snippet 54*ebfedea0SLionel Sambuc * below. This is because the DES_random_key() can fail with an 55*ebfedea0SLionel Sambuc * abort() in case of and failure to start the random generator. 56*ebfedea0SLionel Sambuc * 57*ebfedea0SLionel Sambuc * There is a replacement function DES_new_random_key(), however that 58*ebfedea0SLionel Sambuc * function does not exists in OpenSSL. 59*ebfedea0SLionel Sambuc * 60*ebfedea0SLionel Sambuc * @code 61*ebfedea0SLionel Sambuc * DES_cblock key; 62*ebfedea0SLionel Sambuc * do { 63*ebfedea0SLionel Sambuc * if (RAND_rand(&key, sizeof(key)) != 1) 64*ebfedea0SLionel Sambuc * goto failure; 65*ebfedea0SLionel Sambuc * DES_set_odd_parity(key); 66*ebfedea0SLionel Sambuc * } while (DES_is_weak_key(&key)); 67*ebfedea0SLionel Sambuc * @endcode 68*ebfedea0SLionel Sambuc * 69*ebfedea0SLionel Sambuc * @section des_impl DES implementation history 70*ebfedea0SLionel Sambuc * 71*ebfedea0SLionel Sambuc * There was no complete BSD licensed, fast, GPL compatible 72*ebfedea0SLionel Sambuc * implementation of DES, so Love wrote the part that was missing, 73*ebfedea0SLionel Sambuc * fast key schedule setup and adapted the interface to the orignal 74*ebfedea0SLionel Sambuc * libdes. 75*ebfedea0SLionel Sambuc * 76*ebfedea0SLionel Sambuc * The document that got me started for real was "Efficient 77*ebfedea0SLionel Sambuc * Implementation of the Data Encryption Standard" by Dag Arne Osvik. 78*ebfedea0SLionel Sambuc * I never got to the PC1 transformation was working, instead I used 79*ebfedea0SLionel Sambuc * table-lookup was used for all key schedule setup. The document was 80*ebfedea0SLionel Sambuc * very useful since it de-mystified other implementations for me. 81*ebfedea0SLionel Sambuc * 82*ebfedea0SLionel Sambuc * The core DES function (SBOX + P transformation) is from Richard 83*ebfedea0SLionel Sambuc * Outerbridge public domain DES implementation. My sanity is saved 84*ebfedea0SLionel Sambuc * thanks to his work. Thank you Richard. 85*ebfedea0SLionel Sambuc */ 86*ebfedea0SLionel Sambuc 87*ebfedea0SLionel Sambuc #include <config.h> 88*ebfedea0SLionel Sambuc 89*ebfedea0SLionel Sambuc #define HC_DEPRECATED 90*ebfedea0SLionel Sambuc 91*ebfedea0SLionel Sambuc #include <stdio.h> 92*ebfedea0SLionel Sambuc #include <stdlib.h> 93*ebfedea0SLionel Sambuc #include <string.h> 94*ebfedea0SLionel Sambuc #include <krb5/krb5-types.h> 95*ebfedea0SLionel Sambuc #include <assert.h> 96*ebfedea0SLionel Sambuc 97*ebfedea0SLionel Sambuc #include <krb5/roken.h> 98*ebfedea0SLionel Sambuc 99*ebfedea0SLionel Sambuc #include "des.h" 100*ebfedea0SLionel Sambuc #include "ui.h" 101*ebfedea0SLionel Sambuc 102*ebfedea0SLionel Sambuc static void desx(uint32_t [2], DES_key_schedule *, int); 103*ebfedea0SLionel Sambuc static void IP(uint32_t [2]); 104*ebfedea0SLionel Sambuc static void FP(uint32_t [2]); 105*ebfedea0SLionel Sambuc 106*ebfedea0SLionel Sambuc #include "des-tables.h" 107*ebfedea0SLionel Sambuc 108*ebfedea0SLionel Sambuc #define ROTATE_LEFT28(x,one) \ 109*ebfedea0SLionel Sambuc if (one) { \ 110*ebfedea0SLionel Sambuc x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \ 111*ebfedea0SLionel Sambuc } else { \ 112*ebfedea0SLionel Sambuc x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \ 113*ebfedea0SLionel Sambuc } 114*ebfedea0SLionel Sambuc 115*ebfedea0SLionel Sambuc /** 116*ebfedea0SLionel Sambuc * Set the parity of the key block, used to generate a des key from a 117*ebfedea0SLionel Sambuc * random key. See @ref des_keygen. 118*ebfedea0SLionel Sambuc * 119*ebfedea0SLionel Sambuc * @param key key to fixup the parity for. 120*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 121*ebfedea0SLionel Sambuc */ 122*ebfedea0SLionel Sambuc 123*ebfedea0SLionel Sambuc void 124*ebfedea0SLionel Sambuc DES_set_odd_parity(DES_cblock *key) 125*ebfedea0SLionel Sambuc { 126*ebfedea0SLionel Sambuc unsigned int i; 127*ebfedea0SLionel Sambuc for (i = 0; i < DES_CBLOCK_LEN; i++) 128*ebfedea0SLionel Sambuc (*key)[i] = odd_parity[(*key)[i]]; 129*ebfedea0SLionel Sambuc } 130*ebfedea0SLionel Sambuc 131*ebfedea0SLionel Sambuc /** 132*ebfedea0SLionel Sambuc * Check if the key have correct parity. 133*ebfedea0SLionel Sambuc * 134*ebfedea0SLionel Sambuc * @param key key to check the parity. 135*ebfedea0SLionel Sambuc * @return 1 on success, 0 on failure. 136*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 137*ebfedea0SLionel Sambuc */ 138*ebfedea0SLionel Sambuc 139*ebfedea0SLionel Sambuc int HC_DEPRECATED 140*ebfedea0SLionel Sambuc DES_check_key_parity(DES_cblock *key) 141*ebfedea0SLionel Sambuc { 142*ebfedea0SLionel Sambuc unsigned int i; 143*ebfedea0SLionel Sambuc 144*ebfedea0SLionel Sambuc for (i = 0; i < DES_CBLOCK_LEN; i++) 145*ebfedea0SLionel Sambuc if ((*key)[i] != odd_parity[(*key)[i]]) 146*ebfedea0SLionel Sambuc return 0; 147*ebfedea0SLionel Sambuc return 1; 148*ebfedea0SLionel Sambuc } 149*ebfedea0SLionel Sambuc 150*ebfedea0SLionel Sambuc /* 151*ebfedea0SLionel Sambuc * 152*ebfedea0SLionel Sambuc */ 153*ebfedea0SLionel Sambuc 154*ebfedea0SLionel Sambuc /* FIPS 74 */ 155*ebfedea0SLionel Sambuc static DES_cblock weak_keys[] = { 156*ebfedea0SLionel Sambuc {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */ 157*ebfedea0SLionel Sambuc {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE}, 158*ebfedea0SLionel Sambuc {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, 159*ebfedea0SLionel Sambuc {0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1}, 160*ebfedea0SLionel Sambuc {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */ 161*ebfedea0SLionel Sambuc {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01}, 162*ebfedea0SLionel Sambuc {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1}, 163*ebfedea0SLionel Sambuc {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E}, 164*ebfedea0SLionel Sambuc {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1}, 165*ebfedea0SLionel Sambuc {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01}, 166*ebfedea0SLionel Sambuc {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE}, 167*ebfedea0SLionel Sambuc {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E}, 168*ebfedea0SLionel Sambuc {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E}, 169*ebfedea0SLionel Sambuc {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01}, 170*ebfedea0SLionel Sambuc {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, 171*ebfedea0SLionel Sambuc {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1} 172*ebfedea0SLionel Sambuc }; 173*ebfedea0SLionel Sambuc 174*ebfedea0SLionel Sambuc /** 175*ebfedea0SLionel Sambuc * Checks if the key is any of the weaks keys that makes DES attacks 176*ebfedea0SLionel Sambuc * trival. 177*ebfedea0SLionel Sambuc * 178*ebfedea0SLionel Sambuc * @param key key to check. 179*ebfedea0SLionel Sambuc * 180*ebfedea0SLionel Sambuc * @return 1 if the key is weak, 0 otherwise. 181*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 182*ebfedea0SLionel Sambuc */ 183*ebfedea0SLionel Sambuc 184*ebfedea0SLionel Sambuc int 185*ebfedea0SLionel Sambuc DES_is_weak_key(DES_cblock *key) 186*ebfedea0SLionel Sambuc { 187*ebfedea0SLionel Sambuc int weak = 0; 188*ebfedea0SLionel Sambuc int i; 189*ebfedea0SLionel Sambuc 190*ebfedea0SLionel Sambuc for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) 191*ebfedea0SLionel Sambuc weak ^= (ct_memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0); 192*ebfedea0SLionel Sambuc 193*ebfedea0SLionel Sambuc return !!weak; 194*ebfedea0SLionel Sambuc } 195*ebfedea0SLionel Sambuc 196*ebfedea0SLionel Sambuc /** 197*ebfedea0SLionel Sambuc * Setup a des key schedule from a key. Deprecated function, use 198*ebfedea0SLionel Sambuc * DES_set_key_unchecked() or DES_set_key_checked() instead. 199*ebfedea0SLionel Sambuc * 200*ebfedea0SLionel Sambuc * @param key a key to initialize the key schedule with. 201*ebfedea0SLionel Sambuc * @param ks a key schedule to initialize. 202*ebfedea0SLionel Sambuc * 203*ebfedea0SLionel Sambuc * @return 0 on success 204*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 205*ebfedea0SLionel Sambuc */ 206*ebfedea0SLionel Sambuc 207*ebfedea0SLionel Sambuc int HC_DEPRECATED 208*ebfedea0SLionel Sambuc DES_set_key(DES_cblock *key, DES_key_schedule *ks) 209*ebfedea0SLionel Sambuc { 210*ebfedea0SLionel Sambuc return DES_set_key_checked(key, ks); 211*ebfedea0SLionel Sambuc } 212*ebfedea0SLionel Sambuc 213*ebfedea0SLionel Sambuc /** 214*ebfedea0SLionel Sambuc * Setup a des key schedule from a key. The key is no longer needed 215*ebfedea0SLionel Sambuc * after this transaction and can cleared. 216*ebfedea0SLionel Sambuc * 217*ebfedea0SLionel Sambuc * Does NOT check that the key is weak for or have wrong parity. 218*ebfedea0SLionel Sambuc * 219*ebfedea0SLionel Sambuc * @param key a key to initialize the key schedule with. 220*ebfedea0SLionel Sambuc * @param ks a key schedule to initialize. 221*ebfedea0SLionel Sambuc * 222*ebfedea0SLionel Sambuc * @return 0 on success 223*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 224*ebfedea0SLionel Sambuc */ 225*ebfedea0SLionel Sambuc 226*ebfedea0SLionel Sambuc int 227*ebfedea0SLionel Sambuc DES_set_key_unchecked(DES_cblock *key, DES_key_schedule *ks) 228*ebfedea0SLionel Sambuc { 229*ebfedea0SLionel Sambuc uint32_t t1, t2; 230*ebfedea0SLionel Sambuc uint32_t c, d; 231*ebfedea0SLionel Sambuc int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 }; 232*ebfedea0SLionel Sambuc uint32_t *k = &ks->ks[0]; 233*ebfedea0SLionel Sambuc int i; 234*ebfedea0SLionel Sambuc 235*ebfedea0SLionel Sambuc t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3]; 236*ebfedea0SLionel Sambuc t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7]; 237*ebfedea0SLionel Sambuc 238*ebfedea0SLionel Sambuc c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3) 239*ebfedea0SLionel Sambuc | (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2) 240*ebfedea0SLionel Sambuc | (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1) 241*ebfedea0SLionel Sambuc | (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0) 242*ebfedea0SLionel Sambuc | (pc1_c_4[(t2 >> (4 )) & 0xf] << 3) 243*ebfedea0SLionel Sambuc | (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2) 244*ebfedea0SLionel Sambuc | (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1) 245*ebfedea0SLionel Sambuc | (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0); 246*ebfedea0SLionel Sambuc 247*ebfedea0SLionel Sambuc 248*ebfedea0SLionel Sambuc d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3) 249*ebfedea0SLionel Sambuc | (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2) 250*ebfedea0SLionel Sambuc | (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1) 251*ebfedea0SLionel Sambuc | (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0) 252*ebfedea0SLionel Sambuc | (pc1_d_4[(t1 >> (1 )) & 0xf] << 3) 253*ebfedea0SLionel Sambuc | (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2) 254*ebfedea0SLionel Sambuc | (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1) 255*ebfedea0SLionel Sambuc | (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0); 256*ebfedea0SLionel Sambuc 257*ebfedea0SLionel Sambuc for (i = 0; i < 16; i++) { 258*ebfedea0SLionel Sambuc uint32_t kc, kd; 259*ebfedea0SLionel Sambuc 260*ebfedea0SLionel Sambuc ROTATE_LEFT28(c, shifts[i]); 261*ebfedea0SLionel Sambuc ROTATE_LEFT28(d, shifts[i]); 262*ebfedea0SLionel Sambuc 263*ebfedea0SLionel Sambuc kc = pc2_c_1[(c >> 22) & 0x3f] | 264*ebfedea0SLionel Sambuc pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] | 265*ebfedea0SLionel Sambuc pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] | 266*ebfedea0SLionel Sambuc pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)]; 267*ebfedea0SLionel Sambuc kd = pc2_d_1[(d >> 22) & 0x3f] | 268*ebfedea0SLionel Sambuc pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] | 269*ebfedea0SLionel Sambuc pc2_d_3[ (d >> 7 ) & 0x3f] | 270*ebfedea0SLionel Sambuc pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)]; 271*ebfedea0SLionel Sambuc 272*ebfedea0SLionel Sambuc /* Change to byte order used by the S boxes */ 273*ebfedea0SLionel Sambuc *k = (kc & 0x00fc0000L) << 6; 274*ebfedea0SLionel Sambuc *k |= (kc & 0x00000fc0L) << 10; 275*ebfedea0SLionel Sambuc *k |= (kd & 0x00fc0000L) >> 10; 276*ebfedea0SLionel Sambuc *k++ |= (kd & 0x00000fc0L) >> 6; 277*ebfedea0SLionel Sambuc *k = (kc & 0x0003f000L) << 12; 278*ebfedea0SLionel Sambuc *k |= (kc & 0x0000003fL) << 16; 279*ebfedea0SLionel Sambuc *k |= (kd & 0x0003f000L) >> 4; 280*ebfedea0SLionel Sambuc *k++ |= (kd & 0x0000003fL); 281*ebfedea0SLionel Sambuc } 282*ebfedea0SLionel Sambuc 283*ebfedea0SLionel Sambuc return 0; 284*ebfedea0SLionel Sambuc } 285*ebfedea0SLionel Sambuc 286*ebfedea0SLionel Sambuc /** 287*ebfedea0SLionel Sambuc * Just like DES_set_key_unchecked() except checking that the key is 288*ebfedea0SLionel Sambuc * not weak for or have correct parity. 289*ebfedea0SLionel Sambuc * 290*ebfedea0SLionel Sambuc * @param key a key to initialize the key schedule with. 291*ebfedea0SLionel Sambuc * @param ks a key schedule to initialize. 292*ebfedea0SLionel Sambuc * 293*ebfedea0SLionel Sambuc * @return 0 on success, -1 on invalid parity, -2 on weak key. 294*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 295*ebfedea0SLionel Sambuc */ 296*ebfedea0SLionel Sambuc 297*ebfedea0SLionel Sambuc int 298*ebfedea0SLionel Sambuc DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks) 299*ebfedea0SLionel Sambuc { 300*ebfedea0SLionel Sambuc if (!DES_check_key_parity(key)) { 301*ebfedea0SLionel Sambuc memset(ks, 0, sizeof(*ks)); 302*ebfedea0SLionel Sambuc return -1; 303*ebfedea0SLionel Sambuc } 304*ebfedea0SLionel Sambuc if (DES_is_weak_key(key)) { 305*ebfedea0SLionel Sambuc memset(ks, 0, sizeof(*ks)); 306*ebfedea0SLionel Sambuc return -2; 307*ebfedea0SLionel Sambuc } 308*ebfedea0SLionel Sambuc return DES_set_key_unchecked(key, ks); 309*ebfedea0SLionel Sambuc } 310*ebfedea0SLionel Sambuc 311*ebfedea0SLionel Sambuc /** 312*ebfedea0SLionel Sambuc * Compatibility function for eay libdes, works just like 313*ebfedea0SLionel Sambuc * DES_set_key_checked(). 314*ebfedea0SLionel Sambuc * 315*ebfedea0SLionel Sambuc * @param key a key to initialize the key schedule with. 316*ebfedea0SLionel Sambuc * @param ks a key schedule to initialize. 317*ebfedea0SLionel Sambuc * 318*ebfedea0SLionel Sambuc * @return 0 on success, -1 on invalid parity, -2 on weak key. 319*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 320*ebfedea0SLionel Sambuc */ 321*ebfedea0SLionel Sambuc 322*ebfedea0SLionel Sambuc int 323*ebfedea0SLionel Sambuc DES_key_sched(DES_cblock *key, DES_key_schedule *ks) 324*ebfedea0SLionel Sambuc { 325*ebfedea0SLionel Sambuc return DES_set_key_checked(key, ks); 326*ebfedea0SLionel Sambuc } 327*ebfedea0SLionel Sambuc 328*ebfedea0SLionel Sambuc /* 329*ebfedea0SLionel Sambuc * 330*ebfedea0SLionel Sambuc */ 331*ebfedea0SLionel Sambuc 332*ebfedea0SLionel Sambuc static void 333*ebfedea0SLionel Sambuc load(const unsigned char *b, uint32_t v[2]) 334*ebfedea0SLionel Sambuc { 335*ebfedea0SLionel Sambuc v[0] = b[0] << 24; 336*ebfedea0SLionel Sambuc v[0] |= b[1] << 16; 337*ebfedea0SLionel Sambuc v[0] |= b[2] << 8; 338*ebfedea0SLionel Sambuc v[0] |= b[3] << 0; 339*ebfedea0SLionel Sambuc v[1] = b[4] << 24; 340*ebfedea0SLionel Sambuc v[1] |= b[5] << 16; 341*ebfedea0SLionel Sambuc v[1] |= b[6] << 8; 342*ebfedea0SLionel Sambuc v[1] |= b[7] << 0; 343*ebfedea0SLionel Sambuc } 344*ebfedea0SLionel Sambuc 345*ebfedea0SLionel Sambuc static void 346*ebfedea0SLionel Sambuc store(const uint32_t v[2], unsigned char *b) 347*ebfedea0SLionel Sambuc { 348*ebfedea0SLionel Sambuc b[0] = (v[0] >> 24) & 0xff; 349*ebfedea0SLionel Sambuc b[1] = (v[0] >> 16) & 0xff; 350*ebfedea0SLionel Sambuc b[2] = (v[0] >> 8) & 0xff; 351*ebfedea0SLionel Sambuc b[3] = (v[0] >> 0) & 0xff; 352*ebfedea0SLionel Sambuc b[4] = (v[1] >> 24) & 0xff; 353*ebfedea0SLionel Sambuc b[5] = (v[1] >> 16) & 0xff; 354*ebfedea0SLionel Sambuc b[6] = (v[1] >> 8) & 0xff; 355*ebfedea0SLionel Sambuc b[7] = (v[1] >> 0) & 0xff; 356*ebfedea0SLionel Sambuc } 357*ebfedea0SLionel Sambuc 358*ebfedea0SLionel Sambuc /** 359*ebfedea0SLionel Sambuc * Encrypt/decrypt a block using DES. Also called ECB mode 360*ebfedea0SLionel Sambuc * 361*ebfedea0SLionel Sambuc * @param u data to encrypt 362*ebfedea0SLionel Sambuc * @param ks key schedule to use 363*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 364*ebfedea0SLionel Sambuc * 365*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 366*ebfedea0SLionel Sambuc */ 367*ebfedea0SLionel Sambuc 368*ebfedea0SLionel Sambuc void 369*ebfedea0SLionel Sambuc DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int encp) 370*ebfedea0SLionel Sambuc { 371*ebfedea0SLionel Sambuc IP(u); 372*ebfedea0SLionel Sambuc desx(u, ks, encp); 373*ebfedea0SLionel Sambuc FP(u); 374*ebfedea0SLionel Sambuc } 375*ebfedea0SLionel Sambuc 376*ebfedea0SLionel Sambuc /** 377*ebfedea0SLionel Sambuc * Encrypt/decrypt a block using DES. 378*ebfedea0SLionel Sambuc * 379*ebfedea0SLionel Sambuc * @param input data to encrypt 380*ebfedea0SLionel Sambuc * @param output data to encrypt 381*ebfedea0SLionel Sambuc * @param ks key schedule to use 382*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 383*ebfedea0SLionel Sambuc * 384*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 385*ebfedea0SLionel Sambuc */ 386*ebfedea0SLionel Sambuc 387*ebfedea0SLionel Sambuc void 388*ebfedea0SLionel Sambuc DES_ecb_encrypt(DES_cblock *input, DES_cblock *output, 389*ebfedea0SLionel Sambuc DES_key_schedule *ks, int encp) 390*ebfedea0SLionel Sambuc { 391*ebfedea0SLionel Sambuc uint32_t u[2]; 392*ebfedea0SLionel Sambuc load(*input, u); 393*ebfedea0SLionel Sambuc DES_encrypt(u, ks, encp); 394*ebfedea0SLionel Sambuc store(u, *output); 395*ebfedea0SLionel Sambuc } 396*ebfedea0SLionel Sambuc 397*ebfedea0SLionel Sambuc /** 398*ebfedea0SLionel Sambuc * Encrypt/decrypt a block using DES in Chain Block Cipher mode (cbc). 399*ebfedea0SLionel Sambuc * 400*ebfedea0SLionel Sambuc * The IV must always be diffrent for diffrent input data blocks. 401*ebfedea0SLionel Sambuc * 402*ebfedea0SLionel Sambuc * @param in data to encrypt 403*ebfedea0SLionel Sambuc * @param out data to encrypt 404*ebfedea0SLionel Sambuc * @param length length of data 405*ebfedea0SLionel Sambuc * @param ks key schedule to use 406*ebfedea0SLionel Sambuc * @param iv initial vector to use 407*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 408*ebfedea0SLionel Sambuc * 409*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 410*ebfedea0SLionel Sambuc */ 411*ebfedea0SLionel Sambuc 412*ebfedea0SLionel Sambuc void 413*ebfedea0SLionel Sambuc DES_cbc_encrypt(const void *in, void *out, long length, 414*ebfedea0SLionel Sambuc DES_key_schedule *ks, DES_cblock *iv, int encp) 415*ebfedea0SLionel Sambuc { 416*ebfedea0SLionel Sambuc const unsigned char *input = in; 417*ebfedea0SLionel Sambuc unsigned char *output = out; 418*ebfedea0SLionel Sambuc uint32_t u[2]; 419*ebfedea0SLionel Sambuc uint32_t uiv[2]; 420*ebfedea0SLionel Sambuc 421*ebfedea0SLionel Sambuc load(*iv, uiv); 422*ebfedea0SLionel Sambuc 423*ebfedea0SLionel Sambuc if (encp) { 424*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 425*ebfedea0SLionel Sambuc load(input, u); 426*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 427*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 428*ebfedea0SLionel Sambuc uiv[0] = u[0]; uiv[1] = u[1]; 429*ebfedea0SLionel Sambuc store(u, output); 430*ebfedea0SLionel Sambuc 431*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 432*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 433*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 434*ebfedea0SLionel Sambuc } 435*ebfedea0SLionel Sambuc if (length) { 436*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 437*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 438*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 439*ebfedea0SLionel Sambuc load(tmp, u); 440*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 441*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 442*ebfedea0SLionel Sambuc store(u, output); 443*ebfedea0SLionel Sambuc } 444*ebfedea0SLionel Sambuc } else { 445*ebfedea0SLionel Sambuc uint32_t t[2]; 446*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 447*ebfedea0SLionel Sambuc load(input, u); 448*ebfedea0SLionel Sambuc t[0] = u[0]; t[1] = u[1]; 449*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 0); 450*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 451*ebfedea0SLionel Sambuc store(u, output); 452*ebfedea0SLionel Sambuc uiv[0] = t[0]; uiv[1] = t[1]; 453*ebfedea0SLionel Sambuc 454*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 455*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 456*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 457*ebfedea0SLionel Sambuc } 458*ebfedea0SLionel Sambuc if (length) { 459*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 460*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 461*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 462*ebfedea0SLionel Sambuc load(tmp, u); 463*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 0); 464*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 465*ebfedea0SLionel Sambuc store(u, output); 466*ebfedea0SLionel Sambuc } 467*ebfedea0SLionel Sambuc } 468*ebfedea0SLionel Sambuc uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 469*ebfedea0SLionel Sambuc } 470*ebfedea0SLionel Sambuc 471*ebfedea0SLionel Sambuc /** 472*ebfedea0SLionel Sambuc * Encrypt/decrypt a block using DES in Propagating Cipher Block 473*ebfedea0SLionel Sambuc * Chaining mode. This mode is only used for Kerberos 4, and it should 474*ebfedea0SLionel Sambuc * stay that way. 475*ebfedea0SLionel Sambuc * 476*ebfedea0SLionel Sambuc * The IV must always be diffrent for diffrent input data blocks. 477*ebfedea0SLionel Sambuc * 478*ebfedea0SLionel Sambuc * @param in data to encrypt 479*ebfedea0SLionel Sambuc * @param out data to encrypt 480*ebfedea0SLionel Sambuc * @param length length of data 481*ebfedea0SLionel Sambuc * @param ks key schedule to use 482*ebfedea0SLionel Sambuc * @param iv initial vector to use 483*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 484*ebfedea0SLionel Sambuc * 485*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 486*ebfedea0SLionel Sambuc */ 487*ebfedea0SLionel Sambuc 488*ebfedea0SLionel Sambuc void 489*ebfedea0SLionel Sambuc DES_pcbc_encrypt(const void *in, void *out, long length, 490*ebfedea0SLionel Sambuc DES_key_schedule *ks, DES_cblock *iv, int encp) 491*ebfedea0SLionel Sambuc { 492*ebfedea0SLionel Sambuc const unsigned char *input = in; 493*ebfedea0SLionel Sambuc unsigned char *output = out; 494*ebfedea0SLionel Sambuc uint32_t u[2]; 495*ebfedea0SLionel Sambuc uint32_t uiv[2]; 496*ebfedea0SLionel Sambuc 497*ebfedea0SLionel Sambuc load(*iv, uiv); 498*ebfedea0SLionel Sambuc 499*ebfedea0SLionel Sambuc if (encp) { 500*ebfedea0SLionel Sambuc uint32_t t[2]; 501*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 502*ebfedea0SLionel Sambuc load(input, u); 503*ebfedea0SLionel Sambuc t[0] = u[0]; t[1] = u[1]; 504*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 505*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 506*ebfedea0SLionel Sambuc uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1]; 507*ebfedea0SLionel Sambuc store(u, output); 508*ebfedea0SLionel Sambuc 509*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 510*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 511*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 512*ebfedea0SLionel Sambuc } 513*ebfedea0SLionel Sambuc if (length) { 514*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 515*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 516*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 517*ebfedea0SLionel Sambuc load(tmp, u); 518*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 519*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 520*ebfedea0SLionel Sambuc store(u, output); 521*ebfedea0SLionel Sambuc } 522*ebfedea0SLionel Sambuc } else { 523*ebfedea0SLionel Sambuc uint32_t t[2]; 524*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 525*ebfedea0SLionel Sambuc load(input, u); 526*ebfedea0SLionel Sambuc t[0] = u[0]; t[1] = u[1]; 527*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 0); 528*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 529*ebfedea0SLionel Sambuc store(u, output); 530*ebfedea0SLionel Sambuc uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1]; 531*ebfedea0SLionel Sambuc 532*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 533*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 534*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 535*ebfedea0SLionel Sambuc } 536*ebfedea0SLionel Sambuc if (length) { 537*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 538*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 539*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 540*ebfedea0SLionel Sambuc load(tmp, u); 541*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 0); 542*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 543*ebfedea0SLionel Sambuc } 544*ebfedea0SLionel Sambuc } 545*ebfedea0SLionel Sambuc uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 546*ebfedea0SLionel Sambuc } 547*ebfedea0SLionel Sambuc 548*ebfedea0SLionel Sambuc /* 549*ebfedea0SLionel Sambuc * 550*ebfedea0SLionel Sambuc */ 551*ebfedea0SLionel Sambuc 552*ebfedea0SLionel Sambuc static void 553*ebfedea0SLionel Sambuc _des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2, 554*ebfedea0SLionel Sambuc DES_key_schedule *ks3, int encp) 555*ebfedea0SLionel Sambuc { 556*ebfedea0SLionel Sambuc IP(u); 557*ebfedea0SLionel Sambuc if (encp) { 558*ebfedea0SLionel Sambuc desx(u, ks1, 1); /* IP + FP cancel out each other */ 559*ebfedea0SLionel Sambuc desx(u, ks2, 0); 560*ebfedea0SLionel Sambuc desx(u, ks3, 1); 561*ebfedea0SLionel Sambuc } else { 562*ebfedea0SLionel Sambuc desx(u, ks3, 0); 563*ebfedea0SLionel Sambuc desx(u, ks2, 1); 564*ebfedea0SLionel Sambuc desx(u, ks1, 0); 565*ebfedea0SLionel Sambuc } 566*ebfedea0SLionel Sambuc FP(u); 567*ebfedea0SLionel Sambuc } 568*ebfedea0SLionel Sambuc 569*ebfedea0SLionel Sambuc /** 570*ebfedea0SLionel Sambuc * Encrypt/decrypt a block using triple DES using EDE mode, 571*ebfedea0SLionel Sambuc * encrypt/decrypt/encrypt. 572*ebfedea0SLionel Sambuc * 573*ebfedea0SLionel Sambuc * @param input data to encrypt 574*ebfedea0SLionel Sambuc * @param output data to encrypt 575*ebfedea0SLionel Sambuc * @param ks1 key schedule to use 576*ebfedea0SLionel Sambuc * @param ks2 key schedule to use 577*ebfedea0SLionel Sambuc * @param ks3 key schedule to use 578*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 579*ebfedea0SLionel Sambuc * 580*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 581*ebfedea0SLionel Sambuc */ 582*ebfedea0SLionel Sambuc 583*ebfedea0SLionel Sambuc void 584*ebfedea0SLionel Sambuc DES_ecb3_encrypt(DES_cblock *input, 585*ebfedea0SLionel Sambuc DES_cblock *output, 586*ebfedea0SLionel Sambuc DES_key_schedule *ks1, 587*ebfedea0SLionel Sambuc DES_key_schedule *ks2, 588*ebfedea0SLionel Sambuc DES_key_schedule *ks3, 589*ebfedea0SLionel Sambuc int encp) 590*ebfedea0SLionel Sambuc { 591*ebfedea0SLionel Sambuc uint32_t u[2]; 592*ebfedea0SLionel Sambuc load(*input, u); 593*ebfedea0SLionel Sambuc _des3_encrypt(u, ks1, ks2, ks3, encp); 594*ebfedea0SLionel Sambuc store(u, *output); 595*ebfedea0SLionel Sambuc return; 596*ebfedea0SLionel Sambuc } 597*ebfedea0SLionel Sambuc 598*ebfedea0SLionel Sambuc /** 599*ebfedea0SLionel Sambuc * Encrypt/decrypt using Triple DES in Chain Block Cipher mode (cbc). 600*ebfedea0SLionel Sambuc * 601*ebfedea0SLionel Sambuc * The IV must always be diffrent for diffrent input data blocks. 602*ebfedea0SLionel Sambuc * 603*ebfedea0SLionel Sambuc * @param in data to encrypt 604*ebfedea0SLionel Sambuc * @param out data to encrypt 605*ebfedea0SLionel Sambuc * @param length length of data 606*ebfedea0SLionel Sambuc * @param ks1 key schedule to use 607*ebfedea0SLionel Sambuc * @param ks2 key schedule to use 608*ebfedea0SLionel Sambuc * @param ks3 key schedule to use 609*ebfedea0SLionel Sambuc * @param iv initial vector to use 610*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 611*ebfedea0SLionel Sambuc * 612*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 613*ebfedea0SLionel Sambuc */ 614*ebfedea0SLionel Sambuc 615*ebfedea0SLionel Sambuc void 616*ebfedea0SLionel Sambuc DES_ede3_cbc_encrypt(const void *in, void *out, 617*ebfedea0SLionel Sambuc long length, DES_key_schedule *ks1, 618*ebfedea0SLionel Sambuc DES_key_schedule *ks2, DES_key_schedule *ks3, 619*ebfedea0SLionel Sambuc DES_cblock *iv, int encp) 620*ebfedea0SLionel Sambuc { 621*ebfedea0SLionel Sambuc const unsigned char *input = in; 622*ebfedea0SLionel Sambuc unsigned char *output = out; 623*ebfedea0SLionel Sambuc uint32_t u[2]; 624*ebfedea0SLionel Sambuc uint32_t uiv[2]; 625*ebfedea0SLionel Sambuc 626*ebfedea0SLionel Sambuc load(*iv, uiv); 627*ebfedea0SLionel Sambuc 628*ebfedea0SLionel Sambuc if (encp) { 629*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 630*ebfedea0SLionel Sambuc load(input, u); 631*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 632*ebfedea0SLionel Sambuc _des3_encrypt(u, ks1, ks2, ks3, 1); 633*ebfedea0SLionel Sambuc uiv[0] = u[0]; uiv[1] = u[1]; 634*ebfedea0SLionel Sambuc store(u, output); 635*ebfedea0SLionel Sambuc 636*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 637*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 638*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 639*ebfedea0SLionel Sambuc } 640*ebfedea0SLionel Sambuc if (length) { 641*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 642*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 643*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 644*ebfedea0SLionel Sambuc load(tmp, u); 645*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 646*ebfedea0SLionel Sambuc _des3_encrypt(u, ks1, ks2, ks3, 1); 647*ebfedea0SLionel Sambuc store(u, output); 648*ebfedea0SLionel Sambuc } 649*ebfedea0SLionel Sambuc } else { 650*ebfedea0SLionel Sambuc uint32_t t[2]; 651*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 652*ebfedea0SLionel Sambuc load(input, u); 653*ebfedea0SLionel Sambuc t[0] = u[0]; t[1] = u[1]; 654*ebfedea0SLionel Sambuc _des3_encrypt(u, ks1, ks2, ks3, 0); 655*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 656*ebfedea0SLionel Sambuc store(u, output); 657*ebfedea0SLionel Sambuc uiv[0] = t[0]; uiv[1] = t[1]; 658*ebfedea0SLionel Sambuc 659*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 660*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 661*ebfedea0SLionel Sambuc output += DES_CBLOCK_LEN; 662*ebfedea0SLionel Sambuc } 663*ebfedea0SLionel Sambuc if (length) { 664*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 665*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 666*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 667*ebfedea0SLionel Sambuc load(tmp, u); 668*ebfedea0SLionel Sambuc _des3_encrypt(u, ks1, ks2, ks3, 0); 669*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 670*ebfedea0SLionel Sambuc store(u, output); 671*ebfedea0SLionel Sambuc } 672*ebfedea0SLionel Sambuc } 673*ebfedea0SLionel Sambuc store(uiv, *iv); 674*ebfedea0SLionel Sambuc uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0; 675*ebfedea0SLionel Sambuc } 676*ebfedea0SLionel Sambuc 677*ebfedea0SLionel Sambuc /** 678*ebfedea0SLionel Sambuc * Encrypt/decrypt using DES in cipher feedback mode with 64 bit 679*ebfedea0SLionel Sambuc * feedback. 680*ebfedea0SLionel Sambuc * 681*ebfedea0SLionel Sambuc * The IV must always be diffrent for diffrent input data blocks. 682*ebfedea0SLionel Sambuc * 683*ebfedea0SLionel Sambuc * @param in data to encrypt 684*ebfedea0SLionel Sambuc * @param out data to encrypt 685*ebfedea0SLionel Sambuc * @param length length of data 686*ebfedea0SLionel Sambuc * @param ks key schedule to use 687*ebfedea0SLionel Sambuc * @param iv initial vector to use 688*ebfedea0SLionel Sambuc * @param num offset into in cipher block encryption/decryption stop last time. 689*ebfedea0SLionel Sambuc * @param encp if non zero, encrypt. if zero, decrypt. 690*ebfedea0SLionel Sambuc * 691*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 692*ebfedea0SLionel Sambuc */ 693*ebfedea0SLionel Sambuc 694*ebfedea0SLionel Sambuc void 695*ebfedea0SLionel Sambuc DES_cfb64_encrypt(const void *in, void *out, 696*ebfedea0SLionel Sambuc long length, DES_key_schedule *ks, DES_cblock *iv, 697*ebfedea0SLionel Sambuc int *num, int encp) 698*ebfedea0SLionel Sambuc { 699*ebfedea0SLionel Sambuc const unsigned char *input = in; 700*ebfedea0SLionel Sambuc unsigned char *output = out; 701*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 702*ebfedea0SLionel Sambuc uint32_t uiv[2]; 703*ebfedea0SLionel Sambuc 704*ebfedea0SLionel Sambuc load(*iv, uiv); 705*ebfedea0SLionel Sambuc 706*ebfedea0SLionel Sambuc assert(*num >= 0 && *num < DES_CBLOCK_LEN); 707*ebfedea0SLionel Sambuc 708*ebfedea0SLionel Sambuc if (encp) { 709*ebfedea0SLionel Sambuc int i = *num; 710*ebfedea0SLionel Sambuc 711*ebfedea0SLionel Sambuc while (length > 0) { 712*ebfedea0SLionel Sambuc if (i == 0) 713*ebfedea0SLionel Sambuc DES_encrypt(uiv, ks, 1); 714*ebfedea0SLionel Sambuc store(uiv, tmp); 715*ebfedea0SLionel Sambuc for (; i < DES_CBLOCK_LEN && i < length; i++) { 716*ebfedea0SLionel Sambuc output[i] = tmp[i] ^ input[i]; 717*ebfedea0SLionel Sambuc } 718*ebfedea0SLionel Sambuc if (i == DES_CBLOCK_LEN) 719*ebfedea0SLionel Sambuc load(output, uiv); 720*ebfedea0SLionel Sambuc output += i; 721*ebfedea0SLionel Sambuc input += i; 722*ebfedea0SLionel Sambuc length -= i; 723*ebfedea0SLionel Sambuc if (i == DES_CBLOCK_LEN) 724*ebfedea0SLionel Sambuc i = 0; 725*ebfedea0SLionel Sambuc } 726*ebfedea0SLionel Sambuc store(uiv, *iv); 727*ebfedea0SLionel Sambuc *num = i; 728*ebfedea0SLionel Sambuc } else { 729*ebfedea0SLionel Sambuc int i = *num; 730*ebfedea0SLionel Sambuc unsigned char c; 731*ebfedea0SLionel Sambuc 732*ebfedea0SLionel Sambuc while (length > 0) { 733*ebfedea0SLionel Sambuc if (i == 0) { 734*ebfedea0SLionel Sambuc DES_encrypt(uiv, ks, 1); 735*ebfedea0SLionel Sambuc store(uiv, tmp); 736*ebfedea0SLionel Sambuc } 737*ebfedea0SLionel Sambuc for (; i < DES_CBLOCK_LEN && i < length; i++) { 738*ebfedea0SLionel Sambuc c = input[i]; 739*ebfedea0SLionel Sambuc output[i] = tmp[i] ^ input[i]; 740*ebfedea0SLionel Sambuc (*iv)[i] = c; 741*ebfedea0SLionel Sambuc } 742*ebfedea0SLionel Sambuc output += i; 743*ebfedea0SLionel Sambuc input += i; 744*ebfedea0SLionel Sambuc length -= i; 745*ebfedea0SLionel Sambuc if (i == DES_CBLOCK_LEN) { 746*ebfedea0SLionel Sambuc i = 0; 747*ebfedea0SLionel Sambuc load(*iv, uiv); 748*ebfedea0SLionel Sambuc } 749*ebfedea0SLionel Sambuc } 750*ebfedea0SLionel Sambuc store(uiv, *iv); 751*ebfedea0SLionel Sambuc *num = i; 752*ebfedea0SLionel Sambuc } 753*ebfedea0SLionel Sambuc } 754*ebfedea0SLionel Sambuc 755*ebfedea0SLionel Sambuc /** 756*ebfedea0SLionel Sambuc * Crete a checksum using DES in CBC encryption mode. This mode is 757*ebfedea0SLionel Sambuc * only used for Kerberos 4, and it should stay that way. 758*ebfedea0SLionel Sambuc * 759*ebfedea0SLionel Sambuc * The IV must always be diffrent for diffrent input data blocks. 760*ebfedea0SLionel Sambuc * 761*ebfedea0SLionel Sambuc * @param in data to checksum 762*ebfedea0SLionel Sambuc * @param output the checksum 763*ebfedea0SLionel Sambuc * @param length length of data 764*ebfedea0SLionel Sambuc * @param ks key schedule to use 765*ebfedea0SLionel Sambuc * @param iv initial vector to use 766*ebfedea0SLionel Sambuc * 767*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 768*ebfedea0SLionel Sambuc */ 769*ebfedea0SLionel Sambuc 770*ebfedea0SLionel Sambuc uint32_t 771*ebfedea0SLionel Sambuc DES_cbc_cksum(const void *in, DES_cblock *output, 772*ebfedea0SLionel Sambuc long length, DES_key_schedule *ks, DES_cblock *iv) 773*ebfedea0SLionel Sambuc { 774*ebfedea0SLionel Sambuc const unsigned char *input = in; 775*ebfedea0SLionel Sambuc uint32_t uiv[2]; 776*ebfedea0SLionel Sambuc uint32_t u[2] = { 0, 0 }; 777*ebfedea0SLionel Sambuc 778*ebfedea0SLionel Sambuc load(*iv, uiv); 779*ebfedea0SLionel Sambuc 780*ebfedea0SLionel Sambuc while (length >= DES_CBLOCK_LEN) { 781*ebfedea0SLionel Sambuc load(input, u); 782*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 783*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 784*ebfedea0SLionel Sambuc uiv[0] = u[0]; uiv[1] = u[1]; 785*ebfedea0SLionel Sambuc 786*ebfedea0SLionel Sambuc length -= DES_CBLOCK_LEN; 787*ebfedea0SLionel Sambuc input += DES_CBLOCK_LEN; 788*ebfedea0SLionel Sambuc } 789*ebfedea0SLionel Sambuc if (length) { 790*ebfedea0SLionel Sambuc unsigned char tmp[DES_CBLOCK_LEN]; 791*ebfedea0SLionel Sambuc memcpy(tmp, input, length); 792*ebfedea0SLionel Sambuc memset(tmp + length, 0, DES_CBLOCK_LEN - length); 793*ebfedea0SLionel Sambuc load(tmp, u); 794*ebfedea0SLionel Sambuc u[0] ^= uiv[0]; u[1] ^= uiv[1]; 795*ebfedea0SLionel Sambuc DES_encrypt(u, ks, 1); 796*ebfedea0SLionel Sambuc } 797*ebfedea0SLionel Sambuc if (output) 798*ebfedea0SLionel Sambuc store(u, *output); 799*ebfedea0SLionel Sambuc 800*ebfedea0SLionel Sambuc uiv[0] = 0; u[0] = 0; uiv[1] = 0; 801*ebfedea0SLionel Sambuc return u[1]; 802*ebfedea0SLionel Sambuc } 803*ebfedea0SLionel Sambuc 804*ebfedea0SLionel Sambuc /* 805*ebfedea0SLionel Sambuc * 806*ebfedea0SLionel Sambuc */ 807*ebfedea0SLionel Sambuc 808*ebfedea0SLionel Sambuc static unsigned char 809*ebfedea0SLionel Sambuc bitswap8(unsigned char b) 810*ebfedea0SLionel Sambuc { 811*ebfedea0SLionel Sambuc unsigned char r = 0; 812*ebfedea0SLionel Sambuc int i; 813*ebfedea0SLionel Sambuc for (i = 0; i < 8; i++) { 814*ebfedea0SLionel Sambuc r = r << 1 | (b & 1); 815*ebfedea0SLionel Sambuc b = b >> 1; 816*ebfedea0SLionel Sambuc } 817*ebfedea0SLionel Sambuc return r; 818*ebfedea0SLionel Sambuc } 819*ebfedea0SLionel Sambuc 820*ebfedea0SLionel Sambuc /** 821*ebfedea0SLionel Sambuc * Convert a string to a DES key. Use something like 822*ebfedea0SLionel Sambuc * PKCS5_PBKDF2_HMAC_SHA1() to create key from passwords. 823*ebfedea0SLionel Sambuc * 824*ebfedea0SLionel Sambuc * @param str The string to convert to a key 825*ebfedea0SLionel Sambuc * @param key the resulting key 826*ebfedea0SLionel Sambuc * 827*ebfedea0SLionel Sambuc * @ingroup hcrypto_des 828*ebfedea0SLionel Sambuc */ 829*ebfedea0SLionel Sambuc 830*ebfedea0SLionel Sambuc void 831*ebfedea0SLionel Sambuc DES_string_to_key(const char *str, DES_cblock *key) 832*ebfedea0SLionel Sambuc { 833*ebfedea0SLionel Sambuc const unsigned char *s; 834*ebfedea0SLionel Sambuc unsigned char *k; 835*ebfedea0SLionel Sambuc DES_key_schedule ks; 836*ebfedea0SLionel Sambuc size_t i, len; 837*ebfedea0SLionel Sambuc 838*ebfedea0SLionel Sambuc memset(key, 0, sizeof(*key)); 839*ebfedea0SLionel Sambuc k = *key; 840*ebfedea0SLionel Sambuc s = (const unsigned char *)str; 841*ebfedea0SLionel Sambuc 842*ebfedea0SLionel Sambuc len = strlen(str); 843*ebfedea0SLionel Sambuc for (i = 0; i < len; i++) { 844*ebfedea0SLionel Sambuc if ((i % 16) < 8) 845*ebfedea0SLionel Sambuc k[i % 8] ^= s[i] << 1; 846*ebfedea0SLionel Sambuc else 847*ebfedea0SLionel Sambuc k[7 - (i % 8)] ^= bitswap8(s[i]); 848*ebfedea0SLionel Sambuc } 849*ebfedea0SLionel Sambuc DES_set_odd_parity(key); 850*ebfedea0SLionel Sambuc if (DES_is_weak_key(key)) 851*ebfedea0SLionel Sambuc k[7] ^= 0xF0; 852*ebfedea0SLionel Sambuc DES_set_key(key, &ks); 853*ebfedea0SLionel Sambuc DES_cbc_cksum(s, key, len, &ks, key); 854*ebfedea0SLionel Sambuc memset(&ks, 0, sizeof(ks)); 855*ebfedea0SLionel Sambuc DES_set_odd_parity(key); 856*ebfedea0SLionel Sambuc if (DES_is_weak_key(key)) 857*ebfedea0SLionel Sambuc k[7] ^= 0xF0; 858*ebfedea0SLionel Sambuc } 859*ebfedea0SLionel Sambuc 860*ebfedea0SLionel Sambuc /** 861*ebfedea0SLionel Sambuc * Read password from prompt and create a DES key. Internal uses 862*ebfedea0SLionel Sambuc * DES_string_to_key(). Really, go use a really string2key function 863*ebfedea0SLionel Sambuc * like PKCS5_PBKDF2_HMAC_SHA1(). 864*ebfedea0SLionel Sambuc * 865*ebfedea0SLionel Sambuc * @param key key to convert to 866*ebfedea0SLionel Sambuc * @param prompt prompt to display user 867*ebfedea0SLionel Sambuc * @param verify prompt twice. 868*ebfedea0SLionel Sambuc * 869*ebfedea0SLionel Sambuc * @return 1 on success, non 1 on failure. 870*ebfedea0SLionel Sambuc */ 871*ebfedea0SLionel Sambuc 872*ebfedea0SLionel Sambuc int 873*ebfedea0SLionel Sambuc DES_read_password(DES_cblock *key, char *prompt, int verify) 874*ebfedea0SLionel Sambuc { 875*ebfedea0SLionel Sambuc char buf[512]; 876*ebfedea0SLionel Sambuc int ret; 877*ebfedea0SLionel Sambuc 878*ebfedea0SLionel Sambuc ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify); 879*ebfedea0SLionel Sambuc if (ret == 1) 880*ebfedea0SLionel Sambuc DES_string_to_key(buf, key); 881*ebfedea0SLionel Sambuc return ret; 882*ebfedea0SLionel Sambuc } 883*ebfedea0SLionel Sambuc 884*ebfedea0SLionel Sambuc /* 885*ebfedea0SLionel Sambuc * 886*ebfedea0SLionel Sambuc */ 887*ebfedea0SLionel Sambuc 888*ebfedea0SLionel Sambuc 889*ebfedea0SLionel Sambuc void 890*ebfedea0SLionel Sambuc _DES_ipfp_test(void) 891*ebfedea0SLionel Sambuc { 892*ebfedea0SLionel Sambuc DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2; 893*ebfedea0SLionel Sambuc uint32_t u[2] = { 1, 0 }; 894*ebfedea0SLionel Sambuc IP(u); 895*ebfedea0SLionel Sambuc FP(u); 896*ebfedea0SLionel Sambuc IP(u); 897*ebfedea0SLionel Sambuc FP(u); 898*ebfedea0SLionel Sambuc if (u[0] != 1 || u[1] != 0) 899*ebfedea0SLionel Sambuc abort(); 900*ebfedea0SLionel Sambuc 901*ebfedea0SLionel Sambuc load(k, u); 902*ebfedea0SLionel Sambuc store(u, k2); 903*ebfedea0SLionel Sambuc if (memcmp(k, k2, 8) != 0) 904*ebfedea0SLionel Sambuc abort(); 905*ebfedea0SLionel Sambuc } 906*ebfedea0SLionel Sambuc 907*ebfedea0SLionel Sambuc /* D3DES (V5.09) - 908*ebfedea0SLionel Sambuc * 909*ebfedea0SLionel Sambuc * A portable, public domain, version of the Data Encryption Standard. 910*ebfedea0SLionel Sambuc * 911*ebfedea0SLionel Sambuc * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. 912*ebfedea0SLionel Sambuc * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation 913*ebfedea0SLionel Sambuc * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis 914*ebfedea0SLionel Sambuc * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, 915*ebfedea0SLionel Sambuc * for humouring me on. 916*ebfedea0SLionel Sambuc * 917*ebfedea0SLionel Sambuc * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. 918*ebfedea0SLionel Sambuc * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. 919*ebfedea0SLionel Sambuc */ 920*ebfedea0SLionel Sambuc 921*ebfedea0SLionel Sambuc static uint32_t SP1[64] = { 922*ebfedea0SLionel Sambuc 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, 923*ebfedea0SLionel Sambuc 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, 924*ebfedea0SLionel Sambuc 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, 925*ebfedea0SLionel Sambuc 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, 926*ebfedea0SLionel Sambuc 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, 927*ebfedea0SLionel Sambuc 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, 928*ebfedea0SLionel Sambuc 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, 929*ebfedea0SLionel Sambuc 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, 930*ebfedea0SLionel Sambuc 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, 931*ebfedea0SLionel Sambuc 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, 932*ebfedea0SLionel Sambuc 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, 933*ebfedea0SLionel Sambuc 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, 934*ebfedea0SLionel Sambuc 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, 935*ebfedea0SLionel Sambuc 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, 936*ebfedea0SLionel Sambuc 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, 937*ebfedea0SLionel Sambuc 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; 938*ebfedea0SLionel Sambuc 939*ebfedea0SLionel Sambuc static uint32_t SP2[64] = { 940*ebfedea0SLionel Sambuc 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, 941*ebfedea0SLionel Sambuc 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, 942*ebfedea0SLionel Sambuc 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, 943*ebfedea0SLionel Sambuc 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, 944*ebfedea0SLionel Sambuc 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, 945*ebfedea0SLionel Sambuc 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, 946*ebfedea0SLionel Sambuc 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, 947*ebfedea0SLionel Sambuc 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, 948*ebfedea0SLionel Sambuc 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, 949*ebfedea0SLionel Sambuc 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, 950*ebfedea0SLionel Sambuc 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, 951*ebfedea0SLionel Sambuc 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, 952*ebfedea0SLionel Sambuc 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, 953*ebfedea0SLionel Sambuc 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, 954*ebfedea0SLionel Sambuc 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, 955*ebfedea0SLionel Sambuc 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; 956*ebfedea0SLionel Sambuc 957*ebfedea0SLionel Sambuc static uint32_t SP3[64] = { 958*ebfedea0SLionel Sambuc 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, 959*ebfedea0SLionel Sambuc 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, 960*ebfedea0SLionel Sambuc 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, 961*ebfedea0SLionel Sambuc 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, 962*ebfedea0SLionel Sambuc 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, 963*ebfedea0SLionel Sambuc 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, 964*ebfedea0SLionel Sambuc 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, 965*ebfedea0SLionel Sambuc 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, 966*ebfedea0SLionel Sambuc 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, 967*ebfedea0SLionel Sambuc 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, 968*ebfedea0SLionel Sambuc 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, 969*ebfedea0SLionel Sambuc 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, 970*ebfedea0SLionel Sambuc 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, 971*ebfedea0SLionel Sambuc 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, 972*ebfedea0SLionel Sambuc 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, 973*ebfedea0SLionel Sambuc 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; 974*ebfedea0SLionel Sambuc 975*ebfedea0SLionel Sambuc static uint32_t SP4[64] = { 976*ebfedea0SLionel Sambuc 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 977*ebfedea0SLionel Sambuc 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, 978*ebfedea0SLionel Sambuc 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, 979*ebfedea0SLionel Sambuc 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, 980*ebfedea0SLionel Sambuc 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, 981*ebfedea0SLionel Sambuc 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, 982*ebfedea0SLionel Sambuc 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, 983*ebfedea0SLionel Sambuc 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, 984*ebfedea0SLionel Sambuc 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, 985*ebfedea0SLionel Sambuc 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, 986*ebfedea0SLionel Sambuc 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, 987*ebfedea0SLionel Sambuc 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 988*ebfedea0SLionel Sambuc 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, 989*ebfedea0SLionel Sambuc 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, 990*ebfedea0SLionel Sambuc 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, 991*ebfedea0SLionel Sambuc 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; 992*ebfedea0SLionel Sambuc 993*ebfedea0SLionel Sambuc static uint32_t SP5[64] = { 994*ebfedea0SLionel Sambuc 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, 995*ebfedea0SLionel Sambuc 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, 996*ebfedea0SLionel Sambuc 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, 997*ebfedea0SLionel Sambuc 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, 998*ebfedea0SLionel Sambuc 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, 999*ebfedea0SLionel Sambuc 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, 1000*ebfedea0SLionel Sambuc 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, 1001*ebfedea0SLionel Sambuc 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, 1002*ebfedea0SLionel Sambuc 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, 1003*ebfedea0SLionel Sambuc 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, 1004*ebfedea0SLionel Sambuc 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, 1005*ebfedea0SLionel Sambuc 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, 1006*ebfedea0SLionel Sambuc 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, 1007*ebfedea0SLionel Sambuc 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, 1008*ebfedea0SLionel Sambuc 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, 1009*ebfedea0SLionel Sambuc 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; 1010*ebfedea0SLionel Sambuc 1011*ebfedea0SLionel Sambuc static uint32_t SP6[64] = { 1012*ebfedea0SLionel Sambuc 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, 1013*ebfedea0SLionel Sambuc 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, 1014*ebfedea0SLionel Sambuc 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, 1015*ebfedea0SLionel Sambuc 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, 1016*ebfedea0SLionel Sambuc 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, 1017*ebfedea0SLionel Sambuc 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, 1018*ebfedea0SLionel Sambuc 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, 1019*ebfedea0SLionel Sambuc 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, 1020*ebfedea0SLionel Sambuc 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, 1021*ebfedea0SLionel Sambuc 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, 1022*ebfedea0SLionel Sambuc 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, 1023*ebfedea0SLionel Sambuc 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, 1024*ebfedea0SLionel Sambuc 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, 1025*ebfedea0SLionel Sambuc 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, 1026*ebfedea0SLionel Sambuc 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, 1027*ebfedea0SLionel Sambuc 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; 1028*ebfedea0SLionel Sambuc 1029*ebfedea0SLionel Sambuc static uint32_t SP7[64] = { 1030*ebfedea0SLionel Sambuc 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, 1031*ebfedea0SLionel Sambuc 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, 1032*ebfedea0SLionel Sambuc 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, 1033*ebfedea0SLionel Sambuc 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, 1034*ebfedea0SLionel Sambuc 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, 1035*ebfedea0SLionel Sambuc 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, 1036*ebfedea0SLionel Sambuc 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, 1037*ebfedea0SLionel Sambuc 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, 1038*ebfedea0SLionel Sambuc 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, 1039*ebfedea0SLionel Sambuc 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, 1040*ebfedea0SLionel Sambuc 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, 1041*ebfedea0SLionel Sambuc 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, 1042*ebfedea0SLionel Sambuc 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, 1043*ebfedea0SLionel Sambuc 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, 1044*ebfedea0SLionel Sambuc 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, 1045*ebfedea0SLionel Sambuc 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; 1046*ebfedea0SLionel Sambuc 1047*ebfedea0SLionel Sambuc static uint32_t SP8[64] = { 1048*ebfedea0SLionel Sambuc 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, 1049*ebfedea0SLionel Sambuc 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, 1050*ebfedea0SLionel Sambuc 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, 1051*ebfedea0SLionel Sambuc 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, 1052*ebfedea0SLionel Sambuc 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, 1053*ebfedea0SLionel Sambuc 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, 1054*ebfedea0SLionel Sambuc 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, 1055*ebfedea0SLionel Sambuc 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, 1056*ebfedea0SLionel Sambuc 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, 1057*ebfedea0SLionel Sambuc 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, 1058*ebfedea0SLionel Sambuc 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, 1059*ebfedea0SLionel Sambuc 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, 1060*ebfedea0SLionel Sambuc 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, 1061*ebfedea0SLionel Sambuc 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, 1062*ebfedea0SLionel Sambuc 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, 1063*ebfedea0SLionel Sambuc 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; 1064*ebfedea0SLionel Sambuc 1065*ebfedea0SLionel Sambuc static void 1066*ebfedea0SLionel Sambuc IP(uint32_t v[2]) 1067*ebfedea0SLionel Sambuc { 1068*ebfedea0SLionel Sambuc uint32_t work; 1069*ebfedea0SLionel Sambuc 1070*ebfedea0SLionel Sambuc work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL; 1071*ebfedea0SLionel Sambuc v[1] ^= work; 1072*ebfedea0SLionel Sambuc v[0] ^= (work << 4); 1073*ebfedea0SLionel Sambuc work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL; 1074*ebfedea0SLionel Sambuc v[1] ^= work; 1075*ebfedea0SLionel Sambuc v[0] ^= (work << 16); 1076*ebfedea0SLionel Sambuc work = ((v[1] >> 2) ^ v[0]) & 0x33333333L; 1077*ebfedea0SLionel Sambuc v[0] ^= work; 1078*ebfedea0SLionel Sambuc v[1] ^= (work << 2); 1079*ebfedea0SLionel Sambuc work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL; 1080*ebfedea0SLionel Sambuc v[0] ^= work; 1081*ebfedea0SLionel Sambuc v[1] ^= (work << 8); 1082*ebfedea0SLionel Sambuc v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL; 1083*ebfedea0SLionel Sambuc work = (v[0] ^ v[1]) & 0xaaaaaaaaL; 1084*ebfedea0SLionel Sambuc v[0] ^= work; 1085*ebfedea0SLionel Sambuc v[1] ^= work; 1086*ebfedea0SLionel Sambuc v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL; 1087*ebfedea0SLionel Sambuc } 1088*ebfedea0SLionel Sambuc 1089*ebfedea0SLionel Sambuc static void 1090*ebfedea0SLionel Sambuc FP(uint32_t v[2]) 1091*ebfedea0SLionel Sambuc { 1092*ebfedea0SLionel Sambuc uint32_t work; 1093*ebfedea0SLionel Sambuc 1094*ebfedea0SLionel Sambuc v[0] = (v[0] << 31) | (v[0] >> 1); 1095*ebfedea0SLionel Sambuc work = (v[1] ^ v[0]) & 0xaaaaaaaaL; 1096*ebfedea0SLionel Sambuc v[1] ^= work; 1097*ebfedea0SLionel Sambuc v[0] ^= work; 1098*ebfedea0SLionel Sambuc v[1] = (v[1] << 31) | (v[1] >> 1); 1099*ebfedea0SLionel Sambuc work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL; 1100*ebfedea0SLionel Sambuc v[0] ^= work; 1101*ebfedea0SLionel Sambuc v[1] ^= (work << 8); 1102*ebfedea0SLionel Sambuc work = ((v[1] >> 2) ^ v[0]) & 0x33333333L; 1103*ebfedea0SLionel Sambuc v[0] ^= work; 1104*ebfedea0SLionel Sambuc v[1] ^= (work << 2); 1105*ebfedea0SLionel Sambuc work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL; 1106*ebfedea0SLionel Sambuc v[1] ^= work; 1107*ebfedea0SLionel Sambuc v[0] ^= (work << 16); 1108*ebfedea0SLionel Sambuc work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL; 1109*ebfedea0SLionel Sambuc v[1] ^= work; 1110*ebfedea0SLionel Sambuc v[0] ^= (work << 4); 1111*ebfedea0SLionel Sambuc } 1112*ebfedea0SLionel Sambuc 1113*ebfedea0SLionel Sambuc static void 1114*ebfedea0SLionel Sambuc desx(uint32_t block[2], DES_key_schedule *ks, int encp) 1115*ebfedea0SLionel Sambuc { 1116*ebfedea0SLionel Sambuc uint32_t *keys; 1117*ebfedea0SLionel Sambuc uint32_t fval, work, right, left; 1118*ebfedea0SLionel Sambuc int round; 1119*ebfedea0SLionel Sambuc 1120*ebfedea0SLionel Sambuc left = block[0]; 1121*ebfedea0SLionel Sambuc right = block[1]; 1122*ebfedea0SLionel Sambuc 1123*ebfedea0SLionel Sambuc if (encp) { 1124*ebfedea0SLionel Sambuc keys = &ks->ks[0]; 1125*ebfedea0SLionel Sambuc 1126*ebfedea0SLionel Sambuc for( round = 0; round < 8; round++ ) { 1127*ebfedea0SLionel Sambuc work = (right << 28) | (right >> 4); 1128*ebfedea0SLionel Sambuc work ^= *keys++; 1129*ebfedea0SLionel Sambuc fval = SP7[ work & 0x3fL]; 1130*ebfedea0SLionel Sambuc fval |= SP5[(work >> 8) & 0x3fL]; 1131*ebfedea0SLionel Sambuc fval |= SP3[(work >> 16) & 0x3fL]; 1132*ebfedea0SLionel Sambuc fval |= SP1[(work >> 24) & 0x3fL]; 1133*ebfedea0SLionel Sambuc work = right ^ *keys++; 1134*ebfedea0SLionel Sambuc fval |= SP8[ work & 0x3fL]; 1135*ebfedea0SLionel Sambuc fval |= SP6[(work >> 8) & 0x3fL]; 1136*ebfedea0SLionel Sambuc fval |= SP4[(work >> 16) & 0x3fL]; 1137*ebfedea0SLionel Sambuc fval |= SP2[(work >> 24) & 0x3fL]; 1138*ebfedea0SLionel Sambuc left ^= fval; 1139*ebfedea0SLionel Sambuc work = (left << 28) | (left >> 4); 1140*ebfedea0SLionel Sambuc work ^= *keys++; 1141*ebfedea0SLionel Sambuc fval = SP7[ work & 0x3fL]; 1142*ebfedea0SLionel Sambuc fval |= SP5[(work >> 8) & 0x3fL]; 1143*ebfedea0SLionel Sambuc fval |= SP3[(work >> 16) & 0x3fL]; 1144*ebfedea0SLionel Sambuc fval |= SP1[(work >> 24) & 0x3fL]; 1145*ebfedea0SLionel Sambuc work = left ^ *keys++; 1146*ebfedea0SLionel Sambuc fval |= SP8[ work & 0x3fL]; 1147*ebfedea0SLionel Sambuc fval |= SP6[(work >> 8) & 0x3fL]; 1148*ebfedea0SLionel Sambuc fval |= SP4[(work >> 16) & 0x3fL]; 1149*ebfedea0SLionel Sambuc fval |= SP2[(work >> 24) & 0x3fL]; 1150*ebfedea0SLionel Sambuc right ^= fval; 1151*ebfedea0SLionel Sambuc } 1152*ebfedea0SLionel Sambuc } else { 1153*ebfedea0SLionel Sambuc keys = &ks->ks[30]; 1154*ebfedea0SLionel Sambuc 1155*ebfedea0SLionel Sambuc for( round = 0; round < 8; round++ ) { 1156*ebfedea0SLionel Sambuc work = (right << 28) | (right >> 4); 1157*ebfedea0SLionel Sambuc work ^= *keys++; 1158*ebfedea0SLionel Sambuc fval = SP7[ work & 0x3fL]; 1159*ebfedea0SLionel Sambuc fval |= SP5[(work >> 8) & 0x3fL]; 1160*ebfedea0SLionel Sambuc fval |= SP3[(work >> 16) & 0x3fL]; 1161*ebfedea0SLionel Sambuc fval |= SP1[(work >> 24) & 0x3fL]; 1162*ebfedea0SLionel Sambuc work = right ^ *keys++; 1163*ebfedea0SLionel Sambuc fval |= SP8[ work & 0x3fL]; 1164*ebfedea0SLionel Sambuc fval |= SP6[(work >> 8) & 0x3fL]; 1165*ebfedea0SLionel Sambuc fval |= SP4[(work >> 16) & 0x3fL]; 1166*ebfedea0SLionel Sambuc fval |= SP2[(work >> 24) & 0x3fL]; 1167*ebfedea0SLionel Sambuc left ^= fval; 1168*ebfedea0SLionel Sambuc work = (left << 28) | (left >> 4); 1169*ebfedea0SLionel Sambuc keys -= 4; 1170*ebfedea0SLionel Sambuc work ^= *keys++; 1171*ebfedea0SLionel Sambuc fval = SP7[ work & 0x3fL]; 1172*ebfedea0SLionel Sambuc fval |= SP5[(work >> 8) & 0x3fL]; 1173*ebfedea0SLionel Sambuc fval |= SP3[(work >> 16) & 0x3fL]; 1174*ebfedea0SLionel Sambuc fval |= SP1[(work >> 24) & 0x3fL]; 1175*ebfedea0SLionel Sambuc work = left ^ *keys++; 1176*ebfedea0SLionel Sambuc fval |= SP8[ work & 0x3fL]; 1177*ebfedea0SLionel Sambuc fval |= SP6[(work >> 8) & 0x3fL]; 1178*ebfedea0SLionel Sambuc fval |= SP4[(work >> 16) & 0x3fL]; 1179*ebfedea0SLionel Sambuc fval |= SP2[(work >> 24) & 0x3fL]; 1180*ebfedea0SLionel Sambuc right ^= fval; 1181*ebfedea0SLionel Sambuc keys -= 4; 1182*ebfedea0SLionel Sambuc } 1183*ebfedea0SLionel Sambuc } 1184*ebfedea0SLionel Sambuc block[0] = right; 1185*ebfedea0SLionel Sambuc block[1] = left; 1186*ebfedea0SLionel Sambuc } 1187