Path: blob/main/contrib/bearssl/src/symcipher/des_support.c
39483 views
/*1* Copyright (c) 2016 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#include "inner.h"2526/* see inner.h */27void28br_des_do_IP(uint32_t *xl, uint32_t *xr)29{30/*31* Permutation algorithm is initially from Richard Outerbridge;32* implementation here is adapted from Crypto++ "des.cpp" file33* (which is in public domain).34*/35uint32_t l, r, t;3637l = *xl;38r = *xr;39t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F;40r ^= t;41l ^= t << 4;42t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF;43r ^= t;44l ^= t << 16;45t = ((r >> 2) ^ l) & (uint32_t)0x33333333;46l ^= t;47r ^= t << 2;48t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF;49l ^= t;50r ^= t << 8;51t = ((l >> 1) ^ r) & (uint32_t)0x55555555;52r ^= t;53l ^= t << 1;54*xl = l;55*xr = r;56}5758/* see inner.h */59void60br_des_do_invIP(uint32_t *xl, uint32_t *xr)61{62/*63* See br_des_do_IP().64*/65uint32_t l, r, t;6667l = *xl;68r = *xr;69t = ((l >> 1) ^ r) & 0x55555555;70r ^= t;71l ^= t << 1;72t = ((r >> 8) ^ l) & 0x00FF00FF;73l ^= t;74r ^= t << 8;75t = ((r >> 2) ^ l) & 0x33333333;76l ^= t;77r ^= t << 2;78t = ((l >> 16) ^ r) & 0x0000FFFF;79r ^= t;80l ^= t << 16;81t = ((l >> 4) ^ r) & 0x0F0F0F0F;82r ^= t;83l ^= t << 4;84*xl = l;85*xr = r;86}8788/* see inner.h */89void90br_des_keysched_unit(uint32_t *skey, const void *key)91{92uint32_t xl, xr, kl, kr;93int i;9495xl = br_dec32be(key);96xr = br_dec32be((const unsigned char *)key + 4);9798/*99* Permutation PC-1 is quite similar to the IP permutation.100* Definition of IP (in FIPS 46-3 notations) is:101* 58 50 42 34 26 18 10 2102* 60 52 44 36 28 20 12 4103* 62 54 46 38 30 22 14 6104* 64 56 48 40 32 24 16 8105* 57 49 41 33 25 17 9 1106* 59 51 43 35 27 19 11 3107* 61 53 45 37 29 21 13 5108* 63 55 47 39 31 23 15 7109*110* Definition of PC-1 is:111* 57 49 41 33 25 17 9 1112* 58 50 42 34 26 18 10 2113* 59 51 43 35 27 19 11 3114* 60 52 44 36115* 63 55 47 39 31 23 15 7116* 62 54 46 38 30 22 14 6117* 61 53 45 37 29 21 13 5118* 28 20 12 4119*/120br_des_do_IP(&xl, &xr);121kl = ((xr & (uint32_t)0xFF000000) >> 4)122| ((xl & (uint32_t)0xFF000000) >> 12)123| ((xr & (uint32_t)0x00FF0000) >> 12)124| ((xl & (uint32_t)0x00FF0000) >> 20);125kr = ((xr & (uint32_t)0x000000FF) << 20)126| ((xl & (uint32_t)0x0000FF00) << 4)127| ((xr & (uint32_t)0x0000FF00) >> 4)128| ((xl & (uint32_t)0x000F0000) >> 16);129130/*131* For each round, rotate the two 28-bit words kl and kr.132* The extraction of the 48-bit subkey (PC-2) is not done yet.133*/134for (i = 0; i < 16; i ++) {135if ((1 << i) & 0x8103) {136kl = (kl << 1) | (kl >> 27);137kr = (kr << 1) | (kr >> 27);138} else {139kl = (kl << 2) | (kl >> 26);140kr = (kr << 2) | (kr >> 26);141}142kl &= (uint32_t)0x0FFFFFFF;143kr &= (uint32_t)0x0FFFFFFF;144skey[(i << 1) + 0] = kl;145skey[(i << 1) + 1] = kr;146}147}148149/* see inner.h */150void151br_des_rev_skey(uint32_t *skey)152{153int i;154155for (i = 0; i < 16; i += 2) {156uint32_t t;157158t = skey[i + 0];159skey[i + 0] = skey[30 - i];160skey[30 - i] = t;161t = skey[i + 1];162skey[i + 1] = skey[31 - i];163skey[31 - i] = t;164}165}166167168