Path: blob/main/contrib/bearssl/src/symcipher/des_tab.c
39482 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/*27* PC2left[x] tells where bit x goes when applying PC-2. 'x' is a bit28* position in the left rotated key word. Both position are in normal29* order (rightmost bit is 0).30*/31static const unsigned char PC2left[] = {3216, 3, 7, 24, 20, 11, 24,3313, 2, 10, 24, 22, 5, 15,3423, 1, 9, 21, 12, 24, 6,354, 14, 18, 8, 17, 0, 1936};3738/*39* Similar to PC2left[x], for the right rotated key word.40*/41static const unsigned char PC2right[] = {428, 18, 24, 6, 22, 15, 3,4310, 12, 19, 5, 14, 11, 24,444, 23, 16, 9, 24, 20, 2,4524, 7, 13, 0, 21, 17, 146};4748/*49* S-boxes and PC-1 merged.50*/51static const uint32_t S1[] = {520x00808200, 0x00000000, 0x00008000, 0x00808202,530x00808002, 0x00008202, 0x00000002, 0x00008000,540x00000200, 0x00808200, 0x00808202, 0x00000200,550x00800202, 0x00808002, 0x00800000, 0x00000002,560x00000202, 0x00800200, 0x00800200, 0x00008200,570x00008200, 0x00808000, 0x00808000, 0x00800202,580x00008002, 0x00800002, 0x00800002, 0x00008002,590x00000000, 0x00000202, 0x00008202, 0x00800000,600x00008000, 0x00808202, 0x00000002, 0x00808000,610x00808200, 0x00800000, 0x00800000, 0x00000200,620x00808002, 0x00008000, 0x00008200, 0x00800002,630x00000200, 0x00000002, 0x00800202, 0x00008202,640x00808202, 0x00008002, 0x00808000, 0x00800202,650x00800002, 0x00000202, 0x00008202, 0x00808200,660x00000202, 0x00800200, 0x00800200, 0x00000000,670x00008002, 0x00008200, 0x00000000, 0x0080800268};6970static const uint32_t S2[] = {710x40084010, 0x40004000, 0x00004000, 0x00084010,720x00080000, 0x00000010, 0x40080010, 0x40004010,730x40000010, 0x40084010, 0x40084000, 0x40000000,740x40004000, 0x00080000, 0x00000010, 0x40080010,750x00084000, 0x00080010, 0x40004010, 0x00000000,760x40000000, 0x00004000, 0x00084010, 0x40080000,770x00080010, 0x40000010, 0x00000000, 0x00084000,780x00004010, 0x40084000, 0x40080000, 0x00004010,790x00000000, 0x00084010, 0x40080010, 0x00080000,800x40004010, 0x40080000, 0x40084000, 0x00004000,810x40080000, 0x40004000, 0x00000010, 0x40084010,820x00084010, 0x00000010, 0x00004000, 0x40000000,830x00004010, 0x40084000, 0x00080000, 0x40000010,840x00080010, 0x40004010, 0x40000010, 0x00080010,850x00084000, 0x00000000, 0x40004000, 0x00004010,860x40000000, 0x40080010, 0x40084010, 0x0008400087};8889static const uint32_t S3[] = {900x00000104, 0x04010100, 0x00000000, 0x04010004,910x04000100, 0x00000000, 0x00010104, 0x04000100,920x00010004, 0x04000004, 0x04000004, 0x00010000,930x04010104, 0x00010004, 0x04010000, 0x00000104,940x04000000, 0x00000004, 0x04010100, 0x00000100,950x00010100, 0x04010000, 0x04010004, 0x00010104,960x04000104, 0x00010100, 0x00010000, 0x04000104,970x00000004, 0x04010104, 0x00000100, 0x04000000,980x04010100, 0x04000000, 0x00010004, 0x00000104,990x00010000, 0x04010100, 0x04000100, 0x00000000,1000x00000100, 0x00010004, 0x04010104, 0x04000100,1010x04000004, 0x00000100, 0x00000000, 0x04010004,1020x04000104, 0x00010000, 0x04000000, 0x04010104,1030x00000004, 0x00010104, 0x00010100, 0x04000004,1040x04010000, 0x04000104, 0x00000104, 0x04010000,1050x00010104, 0x00000004, 0x04010004, 0x00010100106};107108static const uint32_t S4[] = {1090x80401000, 0x80001040, 0x80001040, 0x00000040,1100x00401040, 0x80400040, 0x80400000, 0x80001000,1110x00000000, 0x00401000, 0x00401000, 0x80401040,1120x80000040, 0x00000000, 0x00400040, 0x80400000,1130x80000000, 0x00001000, 0x00400000, 0x80401000,1140x00000040, 0x00400000, 0x80001000, 0x00001040,1150x80400040, 0x80000000, 0x00001040, 0x00400040,1160x00001000, 0x00401040, 0x80401040, 0x80000040,1170x00400040, 0x80400000, 0x00401000, 0x80401040,1180x80000040, 0x00000000, 0x00000000, 0x00401000,1190x00001040, 0x00400040, 0x80400040, 0x80000000,1200x80401000, 0x80001040, 0x80001040, 0x00000040,1210x80401040, 0x80000040, 0x80000000, 0x00001000,1220x80400000, 0x80001000, 0x00401040, 0x80400040,1230x80001000, 0x00001040, 0x00400000, 0x80401000,1240x00000040, 0x00400000, 0x00001000, 0x00401040125};126127static const uint32_t S5[] = {1280x00000080, 0x01040080, 0x01040000, 0x21000080,1290x00040000, 0x00000080, 0x20000000, 0x01040000,1300x20040080, 0x00040000, 0x01000080, 0x20040080,1310x21000080, 0x21040000, 0x00040080, 0x20000000,1320x01000000, 0x20040000, 0x20040000, 0x00000000,1330x20000080, 0x21040080, 0x21040080, 0x01000080,1340x21040000, 0x20000080, 0x00000000, 0x21000000,1350x01040080, 0x01000000, 0x21000000, 0x00040080,1360x00040000, 0x21000080, 0x00000080, 0x01000000,1370x20000000, 0x01040000, 0x21000080, 0x20040080,1380x01000080, 0x20000000, 0x21040000, 0x01040080,1390x20040080, 0x00000080, 0x01000000, 0x21040000,1400x21040080, 0x00040080, 0x21000000, 0x21040080,1410x01040000, 0x00000000, 0x20040000, 0x21000000,1420x00040080, 0x01000080, 0x20000080, 0x00040000,1430x00000000, 0x20040000, 0x01040080, 0x20000080144};145146static const uint32_t S6[] = {1470x10000008, 0x10200000, 0x00002000, 0x10202008,1480x10200000, 0x00000008, 0x10202008, 0x00200000,1490x10002000, 0x00202008, 0x00200000, 0x10000008,1500x00200008, 0x10002000, 0x10000000, 0x00002008,1510x00000000, 0x00200008, 0x10002008, 0x00002000,1520x00202000, 0x10002008, 0x00000008, 0x10200008,1530x10200008, 0x00000000, 0x00202008, 0x10202000,1540x00002008, 0x00202000, 0x10202000, 0x10000000,1550x10002000, 0x00000008, 0x10200008, 0x00202000,1560x10202008, 0x00200000, 0x00002008, 0x10000008,1570x00200000, 0x10002000, 0x10000000, 0x00002008,1580x10000008, 0x10202008, 0x00202000, 0x10200000,1590x00202008, 0x10202000, 0x00000000, 0x10200008,1600x00000008, 0x00002000, 0x10200000, 0x00202008,1610x00002000, 0x00200008, 0x10002008, 0x00000000,1620x10202000, 0x10000000, 0x00200008, 0x10002008163};164165static const uint32_t S7[] = {1660x00100000, 0x02100001, 0x02000401, 0x00000000,1670x00000400, 0x02000401, 0x00100401, 0x02100400,1680x02100401, 0x00100000, 0x00000000, 0x02000001,1690x00000001, 0x02000000, 0x02100001, 0x00000401,1700x02000400, 0x00100401, 0x00100001, 0x02000400,1710x02000001, 0x02100000, 0x02100400, 0x00100001,1720x02100000, 0x00000400, 0x00000401, 0x02100401,1730x00100400, 0x00000001, 0x02000000, 0x00100400,1740x02000000, 0x00100400, 0x00100000, 0x02000401,1750x02000401, 0x02100001, 0x02100001, 0x00000001,1760x00100001, 0x02000000, 0x02000400, 0x00100000,1770x02100400, 0x00000401, 0x00100401, 0x02100400,1780x00000401, 0x02000001, 0x02100401, 0x02100000,1790x00100400, 0x00000000, 0x00000001, 0x02100401,1800x00000000, 0x00100401, 0x02100000, 0x00000400,1810x02000001, 0x02000400, 0x00000400, 0x00100001182};183184static const uint32_t S8[] = {1850x08000820, 0x00000800, 0x00020000, 0x08020820,1860x08000000, 0x08000820, 0x00000020, 0x08000000,1870x00020020, 0x08020000, 0x08020820, 0x00020800,1880x08020800, 0x00020820, 0x00000800, 0x00000020,1890x08020000, 0x08000020, 0x08000800, 0x00000820,1900x00020800, 0x00020020, 0x08020020, 0x08020800,1910x00000820, 0x00000000, 0x00000000, 0x08020020,1920x08000020, 0x08000800, 0x00020820, 0x00020000,1930x00020820, 0x00020000, 0x08020800, 0x00000800,1940x00000020, 0x08020020, 0x00000800, 0x00020820,1950x08000800, 0x00000020, 0x08000020, 0x08020000,1960x08020020, 0x08000000, 0x00020000, 0x08000820,1970x00000000, 0x08020820, 0x00020020, 0x08000020,1980x08020000, 0x08000800, 0x08000820, 0x00000000,1990x08020820, 0x00020800, 0x00020800, 0x00000820,2000x00000820, 0x00020020, 0x08000000, 0x08020800201};202203static inline uint32_t204Fconf(uint32_t r0, uint32_t skl, uint32_t skr)205{206uint32_t r1;207208r1 = (r0 << 16) | (r0 >> 16);209return210S1[((r1 >> 11) ^ (skl >> 18)) & 0x3F]211| S2[((r0 >> 23) ^ (skl >> 12)) & 0x3F]212| S3[((r0 >> 19) ^ (skl >> 6)) & 0x3F]213| S4[((r0 >> 15) ^ (skl )) & 0x3F]214| S5[((r0 >> 11) ^ (skr >> 18)) & 0x3F]215| S6[((r0 >> 7) ^ (skr >> 12)) & 0x3F]216| S7[((r0 >> 3) ^ (skr >> 6)) & 0x3F]217| S8[((r1 >> 15) ^ (skr )) & 0x3F];218}219220static void221process_block_unit(uint32_t *pl, uint32_t *pr, const uint32_t *skey)222{223int i;224uint32_t l, r;225226l = *pl;227r = *pr;228for (i = 0; i < 16; i ++) {229uint32_t t;230231t = l ^ Fconf(r, skey[(i << 1) + 0], skey[(i << 1) + 1]);232l = r;233r = t;234}235*pl = r;236*pr = l;237}238239/* see inner.h */240void241br_des_tab_process_block(unsigned num_rounds, const uint32_t *skey, void *block)242{243unsigned char *buf;244uint32_t l, r;245246buf = block;247l = br_dec32be(buf);248r = br_dec32be(buf + 4);249br_des_do_IP(&l, &r);250while (num_rounds -- > 0) {251process_block_unit(&l, &r, skey);252skey += 32;253}254br_des_do_invIP(&l, &r);255br_enc32be(buf, l);256br_enc32be(buf + 4, r);257}258259static void260keysched_unit(uint32_t *skey, const void *key)261{262int i;263264br_des_keysched_unit(skey, key);265266/*267* Apply PC-2 to get the 48-bit subkeys.268*/269for (i = 0; i < 16; i ++) {270uint32_t xl, xr, ul, ur;271int j;272273xl = skey[(i << 1) + 0];274xr = skey[(i << 1) + 1];275ul = 0;276ur = 0;277for (j = 0; j < 28; j ++) {278ul |= (xl & 1) << PC2left[j];279ur |= (xr & 1) << PC2right[j];280xl >>= 1;281xr >>= 1;282}283skey[(i << 1) + 0] = ul;284skey[(i << 1) + 1] = ur;285}286}287288/* see inner.h */289unsigned290br_des_tab_keysched(uint32_t *skey, const void *key, size_t key_len)291{292switch (key_len) {293case 8:294keysched_unit(skey, key);295return 1;296case 16:297keysched_unit(skey, key);298keysched_unit(skey + 32, (const unsigned char *)key + 8);299br_des_rev_skey(skey + 32);300memcpy(skey + 64, skey, 32 * sizeof *skey);301return 3;302default:303keysched_unit(skey, key);304keysched_unit(skey + 32, (const unsigned char *)key + 8);305br_des_rev_skey(skey + 32);306keysched_unit(skey + 64, (const unsigned char *)key + 16);307return 3;308}309}310311312