blowfish.c
Go to the documentation of this file.
1 /**
2  * @file blowfish.c
3  * @brief Blowfish encryption algorithm
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @section Description
28  *
29  * Blowfish is an encryption algorithm designed to encipher and decipher
30  * blocks of 128 bits under control of a 128/192/256-bit secret key
31  *
32  * @author Oryx Embedded SARL (www.oryx-embedded.com)
33  * @version 1.9.6
34  **/
35 
36 //Switch to the appropriate trace level
37 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
38 
39 //Dependencies
40 #include "core/crypto.h"
41 #include "cipher/blowfish.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (BLOWFISH_SUPPORT == ENABLED)
46 
47 //P-array
48 static const uint32_t parray[18] =
49 {
50  0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
51  0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
52  0x9216D5D9, 0x8979FB1B
53 };
54 
55 //S-box 1
56 static const uint32_t sbox1[256] =
57 {
58  0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
59  0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
60  0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
61  0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
62  0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
63  0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
64  0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
65  0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
66  0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
67  0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
68  0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
69  0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
70  0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
71  0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
72  0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
73  0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
74  0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
75  0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
76  0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
77  0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
78  0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
79  0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
80  0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
81  0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
82  0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
83  0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
84  0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
85  0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
86  0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
87  0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
88  0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
89  0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
90 };
91 
92 //S-box 2
93 static const uint32_t sbox2[256] =
94 {
95  0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
96  0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
97  0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
98  0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
99  0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
100  0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
101  0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
102  0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
103  0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
104  0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
105  0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
106  0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
107  0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
108  0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
109  0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
110  0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
111  0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
112  0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
113  0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
114  0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
115  0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
116  0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
117  0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
118  0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
119  0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
120  0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
121  0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
122  0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
123  0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
124  0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
125  0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
126  0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
127 };
128 
129 //S-box 3
130 static const uint32_t sbox3[256] =
131 {
132  0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
133  0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
134  0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
135  0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
136  0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
137  0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
138  0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
139  0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
140  0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
141  0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
142  0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
143  0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
144  0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
145  0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
146  0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
147  0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
148  0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
149  0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
150  0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
151  0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
152  0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
153  0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
154  0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
155  0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
156  0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
157  0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
158  0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
159  0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
160  0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
161  0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
162  0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
163  0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
164 };
165 
166 //S-box 4
167 static const uint32_t sbox4[256] =
168 {
169  0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
170  0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
171  0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
172  0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
173  0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
174  0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
175  0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
176  0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
177  0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
178  0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
179  0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
180  0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
181  0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
182  0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
183  0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
184  0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
185  0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
186  0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
187  0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
188  0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
189  0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
190  0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
191  0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
192  0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
193  0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
194  0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
195  0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
196  0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
197  0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
198  0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
199  0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
200  0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
201 };
202 
203 //Common interface for encryption algorithms
205 {
206  "Blowfish",
207  sizeof(BlowfishContext),
211  NULL,
212  NULL,
215 };
216 
217 
218 /**
219  * @brief Initialize a Blowfish context using the supplied key
220  * @param[in] context Pointer to the Blowfish context to initialize
221  * @param[in] key Pointer to the key
222  * @param[in] keyLen Length of the key
223  * @return Error code
224  **/
225 
226 error_t blowfishInit(BlowfishContext *context, const uint8_t *key,
227  size_t keyLen)
228 {
229  error_t error;
230 
231  //Check parameters
232  if(context == NULL || key == NULL)
234 
235  //Initialize Blowfish state
236  error = blowfishInitState(context);
237 
238  //Check status code
239  if(!error)
240  {
241  //Perform key expansion
242  error = blowfishExpandKey(context, NULL, 0, key, keyLen);
243  }
244 
245  //Return status code
246  return error;
247 }
248 
249 
250 /**
251  * @brief Blowfish state initialization
252  * @param[in] context Pointer to the Blowfish context
253  * @return Error code
254  **/
255 
257 {
258  uint_t i;
259 
260  //Blowfish uses an initial P-array derived from the hexadecimal digits of pi
261  for(i = 0; i < 18; i++)
262  {
263  context->p[i] = parray[i];
264  }
265 
266  //Blowfish uses initial S-boxes derived from the hexadecimal digits of pi
267  for(i = 0; i < 256; i++)
268  {
269  context->s1[i] = sbox1[i];
270  context->s2[i] = sbox2[i];
271  context->s3[i] = sbox3[i];
272  context->s4[i] = sbox4[i];
273  }
274 
275  //Successful processing
276  return NO_ERROR;
277 }
278 
279 
280 /**
281  * @brief Key expansion
282  * @param[in] context Pointer to the Blowfish context
283  * @param[in] salt Random salt
284  * @param[in] saltLen Length of the random salt, in bytes
285  * @param[in] key Secret key
286  * @param[in] keyLen Length of the secret key, in bytes
287  * @return Error code
288  **/
289 
290 error_t blowfishExpandKey(BlowfishContext *context, const uint8_t *salt,
291  size_t saltLen, const uint8_t *key, size_t keyLen)
292 {
293  uint_t i;
294  uint_t j;
295  uint32_t value;
296  size_t keyIndex;
297  size_t saltIndex;
298  uint8_t data[BLOWFISH_BLOCK_SIZE];
299 
300  //Check the length of the salt
301  if(saltLen != 0 && saltLen < BLOWFISH_BLOCK_SIZE)
303 
304  //Check the length of the key
305  if(keyLen == 0)
307 
308  //Initialize variables
309  keyIndex = 0;
310  saltIndex = 0;
311 
312  //In the first phase of setting up the P-array, the secret key K is
313  //cyclically XOR'd into the P-array
314  for(i = 0; i < 18; i++)
315  {
316  //This is done by taking successive 32-bit quantities of K
317  for(value = 0, j = 0; j < 4; j++)
318  {
319  //Read current byte
320  value = (value << 8) | key[keyIndex];
321 
322  //Wrap around to the start if the end of the key is reached
323  if(++keyIndex >= keyLen)
324  {
325  keyIndex = 0;
326  }
327  }
328 
329  //XOR the 32-bit quantities of K with the P-array elements
330  context->p[i] ^= value;
331  }
332 
333  //Initialize the 64-bit data block to all zeroes
335 
336  //In the second phase, the 64-bit data block is repeatedly encrypted to
337  //yield the final P-array
338  for(i = 0; i < 18; i += 2)
339  {
340  //The data block is XOR'd with the salt
341  blowfishXorBlock(data, salt, saltLen, &saltIndex);
342 
343  //Encrypt the data block
344  blowfishEncryptBlock(context, data, data);
345  context->p[i] = LOAD32BE(data);
346  context->p[i + 1] = LOAD32BE(data + 4);
347  }
348 
349  //The process used for the second phase of the P-array initialisation is
350  //now repeated to initialize the S-boxes
351  for(i = 0; i < 256; i += 2)
352  {
353  //The data block is XOR'd with the salt
354  blowfishXorBlock(data, salt, saltLen, &saltIndex);
355 
356  //Encrypt the data block
357  blowfishEncryptBlock(context, data, data);
358  context->s1[i] = LOAD32BE(data);
359  context->s1[i + 1] = LOAD32BE(data + 4);
360  }
361 
362  //Initialize S-box 2
363  for(i = 0; i < 256; i += 2)
364  {
365  //The data block is XOR'd with the salt
366  blowfishXorBlock(data, salt, saltLen, &saltIndex);
367 
368  //Encrypt the data block
369  blowfishEncryptBlock(context, data, data);
370  context->s2[i] = LOAD32BE(data);
371  context->s2[i + 1] = LOAD32BE(data + 4);
372  }
373 
374  //Initialize S-box 3
375  for(i = 0; i < 256; i += 2)
376  {
377  //The data block is XOR'd with the salt
378  blowfishXorBlock(data, salt, saltLen, &saltIndex);
379 
380  //Encrypt the data block
381  blowfishEncryptBlock(context, data, data);
382  context->s3[i] = LOAD32BE(data);
383  context->s3[i + 1] = LOAD32BE(data + 4);
384  }
385 
386  //Initialize S-box 4
387  for(i = 0; i < 256; i += 2)
388  {
389  //The data block is XOR'd with the salt
390  blowfishXorBlock(data, salt, saltLen, &saltIndex);
391 
392  //Encrypt the data block
393  blowfishEncryptBlock(context, data, data);
394  context->s4[i] = LOAD32BE(data);
395  context->s4[i + 1] = LOAD32BE(data + 4);
396  }
397 
398  //Successful processing
399  return NO_ERROR;
400 }
401 
402 
403 /**
404  * @brief Encrypt a 16-byte block using Blowfish algorithm
405  * @param[in] context Pointer to the Blowfish context
406  * @param[in] input Plaintext block to encrypt
407  * @param[out] output Ciphertext block resulting from encryption
408  **/
409 
410 void blowfishEncryptBlock(BlowfishContext *context, const uint8_t *input,
411  uint8_t *output)
412 {
413  uint_t i;
414  uint32_t left;
415  uint32_t right;
416  uint32_t temp;
417 
418  //Divide the plaintext into two 32-bit halves (L and R)
419  left = LOAD32BE(input + 0);
420  right = LOAD32BE(input + 4);
421 
422  //16 rounds of computation are needed
423  for(i = 0; i < 16; i += 2)
424  {
425  //Apply odd round function
426  left ^= context->p[i];
427  temp = context->s1[(left >> 24) & 0xFF];
428  temp += context->s2[(left >> 16) & 0xFF];
429  temp ^= context->s3[(left >> 8) & 0xFF];
430  temp += context->s4[left & 0xFF];
431  right ^= temp;
432 
433  //Apply even round function
434  right ^= context->p[i + 1];
435  temp = context->s1[(right >> 24) & 0xFF];
436  temp += context->s2[(right >> 16) & 0xFF];
437  temp ^= context->s3[(right >> 8) & 0xFF];
438  temp += context->s4[right & 0xFF];
439  left ^= temp;
440  }
441 
442  //The rounds are followed by two final XOR's with the last elements of
443  //the P-array
444  left ^= context->p[16];
445  right ^= context->p[17];
446 
447  //Recombine L and R
448  STORE32BE(right, output + 0);
449  STORE32BE(left, output + 4);
450 }
451 
452 
453 /**
454  * @brief Decrypt a 16-byte block using Blowfish algorithm
455  * @param[in] context Pointer to the Blowfish context
456  * @param[in] input Ciphertext block to decrypt
457  * @param[out] output Plaintext block resulting from decryption
458  **/
459 
460 void blowfishDecryptBlock(BlowfishContext *context, const uint8_t *input,
461  uint8_t *output)
462 {
463  uint_t i;
464  uint32_t left;
465  uint32_t right;
466  uint32_t temp;
467 
468  //Divide the ciphertext into two 32-bit halves (L and R)
469  right = LOAD32BE(input + 0);
470  left = LOAD32BE(input + 4);
471 
472  //16 rounds of computation are needed
473  for(i = 16; i > 0; i -= 2)
474  {
475  //Apply even round function
476  right ^= context->p[i + 1];
477  temp = context->s1[(right >> 24) & 0xFF];
478  temp += context->s2[(right >> 16) & 0xFF];
479  temp ^= context->s3[(right >> 8) & 0xFF];
480  temp += context->s4[right & 0xFF];
481  left ^= temp;
482 
483  //Apply odd round function
484  left ^= context->p[i];
485  temp = context->s1[(left >> 24) & 0xFF];
486  temp += context->s2[(left >> 16) & 0xFF];
487  temp ^= context->s3[(left >> 8) & 0xFF];
488  temp += context->s4[left & 0xFF];
489  right ^= temp;
490  }
491 
492  //The rounds are followed by two final XOR's with the first elements of
493  //the P-array
494  right ^= context->p[1];
495  left ^= context->p[0];
496 
497  //Recombine L and R
498  STORE32BE(left, output + 0);
499  STORE32BE(right, output + 4);
500 }
501 
502 
503 /**
504  * @brief XOR data block with random salt
505  * @param[in,out] data Pointer the data block (16 bytes)
506  * @param[in] salt Pointer to the random salt (16 bytes)
507  * @param[in] saltLen Length of the salt, in bytes
508  * @param[in,out] saltIndex Current salt index
509  **/
510 
511 void blowfishXorBlock(uint8_t *data, const uint8_t *salt, size_t saltLen,
512  size_t *saltIndex)
513 {
514  size_t i;
515  size_t n;
516 
517  //The salt parameter is optional
518  if(saltLen > 0)
519  {
520  //Get current salt index
521  n = *saltIndex;
522 
523  //XOR the data block with the random salt
524  for(i = 0; i < BLOWFISH_BLOCK_SIZE; i++)
525  {
526  //Perform XOR operation
527  data[i] ^= salt[n];
528 
529  //Treat the salt as cyclic
530  if(++n >= saltLen)
531  {
532  n = 0;
533  }
534  }
535 
536  //Save current salt index
537  *saltIndex = n;
538  }
539 }
540 
541 #endif
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1103
#define LOAD32BE(p)
Definition: cpu_endian.h:194
uint32_t s3[256]
Definition: blowfish.h:57
uint32_t p[18]
Definition: blowfish.h:54
error_t blowfishInitState(BlowfishContext *context)
Blowfish state initialization.
Definition: blowfish.c:256
error_t blowfishExpandKey(BlowfishContext *context, const uint8_t *salt, size_t saltLen, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: blowfish.c:290
uint32_t s4[256]
Definition: blowfish.h:58
uint32_t s1[256]
Definition: blowfish.h:55
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:42
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1104
error_t blowfishInit(BlowfishContext *context, const uint8_t *key, size_t keyLen)
Initialize a Blowfish context using the supplied key.
Definition: blowfish.c:226
General definitions for cryptographic algorithms.
Blowfish encryption algorithm.
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:1100
void blowfishEncryptBlock(BlowfishContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 16-byte block using Blowfish algorithm.
Definition: blowfish.c:410
#define cryptoMemset(p, value, length)
Definition: crypto.h:636
uint8_t n
Blowfish algorithm context.
Definition: blowfish.h:52
const CipherAlgo blowfishCipherAlgo
Definition: blowfish.c:204
Common interface for encryption algorithms.
Definition: crypto.h:1150
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
uint8_t data[]
Definition: dtls_misc.h:176
uint32_t s2[256]
Definition: blowfish.h:56
#define BLOWFISH_BLOCK_SIZE
Definition: blowfish.h:38
void blowfishDecryptBlock(BlowfishContext *context, const uint8_t *input, uint8_t *output)
Decrypt a 16-byte block using Blowfish algorithm.
Definition: blowfish.c:460
#define STORE32BE(a, p)
Definition: cpu_endian.h:270
void blowfishXorBlock(uint8_t *data, const uint8_t *salt, size_t saltLen, size_t *saltIndex)
XOR data block with random salt.
Definition: blowfish.c:511
Success.
Definition: error.h:44
Debugging facilities.