1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 /* see inner.h */ 28 void 29 br_des_do_IP(uint32_t *xl, uint32_t *xr) 30 { 31 /* 32 * Permutation algorithm is initially from Richard Outerbridge; 33 * implementation here is adapted from Crypto++ "des.cpp" file 34 * (which is in public domain). 35 */ 36 uint32_t l, r, t; 37 38 l = *xl; 39 r = *xr; 40 t = ((l >> 4) ^ r) & (uint32_t)0x0F0F0F0F; 41 r ^= t; 42 l ^= t << 4; 43 t = ((l >> 16) ^ r) & (uint32_t)0x0000FFFF; 44 r ^= t; 45 l ^= t << 16; 46 t = ((r >> 2) ^ l) & (uint32_t)0x33333333; 47 l ^= t; 48 r ^= t << 2; 49 t = ((r >> 8) ^ l) & (uint32_t)0x00FF00FF; 50 l ^= t; 51 r ^= t << 8; 52 t = ((l >> 1) ^ r) & (uint32_t)0x55555555; 53 r ^= t; 54 l ^= t << 1; 55 *xl = l; 56 *xr = r; 57 } 58 59 /* see inner.h */ 60 void 61 br_des_do_invIP(uint32_t *xl, uint32_t *xr) 62 { 63 /* 64 * See br_des_do_IP(). 65 */ 66 uint32_t l, r, t; 67 68 l = *xl; 69 r = *xr; 70 t = ((l >> 1) ^ r) & 0x55555555; 71 r ^= t; 72 l ^= t << 1; 73 t = ((r >> 8) ^ l) & 0x00FF00FF; 74 l ^= t; 75 r ^= t << 8; 76 t = ((r >> 2) ^ l) & 0x33333333; 77 l ^= t; 78 r ^= t << 2; 79 t = ((l >> 16) ^ r) & 0x0000FFFF; 80 r ^= t; 81 l ^= t << 16; 82 t = ((l >> 4) ^ r) & 0x0F0F0F0F; 83 r ^= t; 84 l ^= t << 4; 85 *xl = l; 86 *xr = r; 87 } 88 89 /* see inner.h */ 90 void 91 br_des_keysched_unit(uint32_t *skey, const void *key) 92 { 93 uint32_t xl, xr, kl, kr; 94 int i; 95 96 xl = br_dec32be(key); 97 xr = br_dec32be((const unsigned char *)key + 4); 98 99 /* 100 * Permutation PC-1 is quite similar to the IP permutation. 101 * Definition of IP (in FIPS 46-3 notations) is: 102 * 58 50 42 34 26 18 10 2 103 * 60 52 44 36 28 20 12 4 104 * 62 54 46 38 30 22 14 6 105 * 64 56 48 40 32 24 16 8 106 * 57 49 41 33 25 17 9 1 107 * 59 51 43 35 27 19 11 3 108 * 61 53 45 37 29 21 13 5 109 * 63 55 47 39 31 23 15 7 110 * 111 * Definition of PC-1 is: 112 * 57 49 41 33 25 17 9 1 113 * 58 50 42 34 26 18 10 2 114 * 59 51 43 35 27 19 11 3 115 * 60 52 44 36 116 * 63 55 47 39 31 23 15 7 117 * 62 54 46 38 30 22 14 6 118 * 61 53 45 37 29 21 13 5 119 * 28 20 12 4 120 */ 121 br_des_do_IP(&xl, &xr); 122 kl = ((xr & (uint32_t)0xFF000000) >> 4) 123 | ((xl & (uint32_t)0xFF000000) >> 12) 124 | ((xr & (uint32_t)0x00FF0000) >> 12) 125 | ((xl & (uint32_t)0x00FF0000) >> 20); 126 kr = ((xr & (uint32_t)0x000000FF) << 20) 127 | ((xl & (uint32_t)0x0000FF00) << 4) 128 | ((xr & (uint32_t)0x0000FF00) >> 4) 129 | ((xl & (uint32_t)0x000F0000) >> 16); 130 131 /* 132 * For each round, rotate the two 28-bit words kl and kr. 133 * The extraction of the 48-bit subkey (PC-2) is not done yet. 134 */ 135 for (i = 0; i < 16; i ++) { 136 if ((1 << i) & 0x8103) { 137 kl = (kl << 1) | (kl >> 27); 138 kr = (kr << 1) | (kr >> 27); 139 } else { 140 kl = (kl << 2) | (kl >> 26); 141 kr = (kr << 2) | (kr >> 26); 142 } 143 kl &= (uint32_t)0x0FFFFFFF; 144 kr &= (uint32_t)0x0FFFFFFF; 145 skey[(i << 1) + 0] = kl; 146 skey[(i << 1) + 1] = kr; 147 } 148 } 149 150 /* see inner.h */ 151 void 152 br_des_rev_skey(uint32_t *skey) 153 { 154 int i; 155 156 for (i = 0; i < 16; i += 2) { 157 uint32_t t; 158 159 t = skey[i + 0]; 160 skey[i + 0] = skey[30 - i]; 161 skey[30 - i] = t; 162 t = skey[i + 1]; 163 skey[i + 1] = skey[31 - i]; 164 skey[31 - i] = t; 165 } 166 } 167