]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/src/symcipher/des_support.c
MFV r356163,r356197:
[FreeBSD/FreeBSD.git] / contrib / bearssl / src / symcipher / des_support.c
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 }