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-2024 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 2.4.4
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,
216 };
217 
218 
219 /**
220  * @brief Initialize a Blowfish context using the supplied key
221  * @param[in] context Pointer to the Blowfish context to initialize
222  * @param[in] key Pointer to the key
223  * @param[in] keyLen Length of the key
224  * @return Error code
225  **/
226 
227 error_t blowfishInit(BlowfishContext *context, const uint8_t *key,
228  size_t keyLen)
229 {
230  error_t error;
231 
232  //Check parameters
233  if(context == NULL || key == NULL)
235 
236  //Initialize Blowfish state
237  error = blowfishInitState(context);
238 
239  //Check status code
240  if(!error)
241  {
242  //Perform key expansion
243  error = blowfishExpandKey(context, NULL, 0, key, keyLen);
244  }
245 
246  //Return status code
247  return error;
248 }
249 
250 
251 /**
252  * @brief Blowfish state initialization
253  * @param[in] context Pointer to the Blowfish context
254  * @return Error code
255  **/
256 
258 {
259  uint_t i;
260 
261  //Blowfish uses an initial P-array derived from the hexadecimal digits of pi
262  for(i = 0; i < 18; i++)
263  {
264  context->p[i] = parray[i];
265  }
266 
267  //Blowfish uses initial S-boxes derived from the hexadecimal digits of pi
268  for(i = 0; i < 256; i++)
269  {
270  context->s1[i] = sbox1[i];
271  context->s2[i] = sbox2[i];
272  context->s3[i] = sbox3[i];
273  context->s4[i] = sbox4[i];
274  }
275 
276  //Successful processing
277  return NO_ERROR;
278 }
279 
280 
281 /**
282  * @brief Key expansion
283  * @param[in] context Pointer to the Blowfish context
284  * @param[in] salt Random salt
285  * @param[in] saltLen Length of the random salt, in bytes
286  * @param[in] key Secret key
287  * @param[in] keyLen Length of the secret key, in bytes
288  * @return Error code
289  **/
290 
291 error_t blowfishExpandKey(BlowfishContext *context, const uint8_t *salt,
292  size_t saltLen, const uint8_t *key, size_t keyLen)
293 {
294  uint_t i;
295  uint_t j;
296  uint32_t value;
297  size_t keyIndex;
298  size_t saltIndex;
299  uint8_t data[BLOWFISH_BLOCK_SIZE];
300 
301  //Check the length of the salt
302  if(saltLen != 0 && saltLen < BLOWFISH_BLOCK_SIZE)
304 
305  //Check the length of the key
306  if(keyLen == 0)
308 
309  //Initialize variables
310  keyIndex = 0;
311  saltIndex = 0;
312 
313  //In the first phase of setting up the P-array, the secret key K is
314  //cyclically XOR'd into the P-array
315  for(i = 0; i < 18; i++)
316  {
317  //This is done by taking successive 32-bit quantities of K
318  for(value = 0, j = 0; j < 4; j++)
319  {
320  //Read current byte
321  value = (value << 8) | key[keyIndex];
322 
323  //Wrap around to the start if the end of the key is reached
324  if(++keyIndex >= keyLen)
325  {
326  keyIndex = 0;
327  }
328  }
329 
330  //XOR the 32-bit quantities of K with the P-array elements
331  context->p[i] ^= value;
332  }
333 
334  //Initialize the 64-bit data block to all zeroes
336 
337  //In the second phase, the 64-bit data block is repeatedly encrypted to
338  //yield the final P-array
339  for(i = 0; i < 18; i += 2)
340  {
341  //The data block is XOR'd with the salt
342  blowfishXorBlock(data, salt, saltLen, &saltIndex);
343 
344  //Encrypt the data block
345  blowfishEncryptBlock(context, data, data);
346  context->p[i] = LOAD32BE(data);
347  context->p[i + 1] = LOAD32BE(data + 4);
348  }
349 
350  //The process used for the second phase of the P-array initialization is
351  //now repeated to initialize the S-boxes
352  for(i = 0; i < 256; i += 2)
353  {
354  //The data block is XOR'd with the salt
355  blowfishXorBlock(data, salt, saltLen, &saltIndex);
356 
357  //Encrypt the data block
358  blowfishEncryptBlock(context, data, data);
359  context->s1[i] = LOAD32BE(data);
360  context->s1[i + 1] = LOAD32BE(data + 4);
361  }
362 
363  //Initialize S-box 2
364  for(i = 0; i < 256; i += 2)
365  {
366  //The data block is XOR'd with the salt
367  blowfishXorBlock(data, salt, saltLen, &saltIndex);
368 
369  //Encrypt the data block
370  blowfishEncryptBlock(context, data, data);
371  context->s2[i] = LOAD32BE(data);
372  context->s2[i + 1] = LOAD32BE(data + 4);
373  }
374 
375  //Initialize S-box 3
376  for(i = 0; i < 256; i += 2)
377  {
378  //The data block is XOR'd with the salt
379  blowfishXorBlock(data, salt, saltLen, &saltIndex);
380 
381  //Encrypt the data block
382  blowfishEncryptBlock(context, data, data);
383  context->s3[i] = LOAD32BE(data);
384  context->s3[i + 1] = LOAD32BE(data + 4);
385  }
386 
387  //Initialize S-box 4
388  for(i = 0; i < 256; i += 2)
389  {
390  //The data block is XOR'd with the salt
391  blowfishXorBlock(data, salt, saltLen, &saltIndex);
392 
393  //Encrypt the data block
394  blowfishEncryptBlock(context, data, data);
395  context->s4[i] = LOAD32BE(data);
396  context->s4[i + 1] = LOAD32BE(data + 4);
397  }
398 
399  //Successful processing
400  return NO_ERROR;
401 }
402 
403 
404 /**
405  * @brief Encrypt a 8-byte block using Blowfish algorithm
406  * @param[in] context Pointer to the Blowfish context
407  * @param[in] input Plaintext block to encrypt
408  * @param[out] output Ciphertext block resulting from encryption
409  **/
410 
411 void blowfishEncryptBlock(BlowfishContext *context, const uint8_t *input,
412  uint8_t *output)
413 {
414  uint_t i;
415  uint32_t l;
416  uint32_t r;
417  uint32_t t;
418 
419  //Divide the plaintext into two 32-bit halves (L and R)
420  l = LOAD32BE(input + 0);
421  r = LOAD32BE(input + 4);
422 
423  //16 rounds of computation are needed
424  for(i = 0; i < 16; i += 2)
425  {
426  //Apply odd round function
427  l ^= context->p[i];
428  t = context->s1[(l >> 24) & 0xFF];
429  t += context->s2[(l >> 16) & 0xFF];
430  t ^= context->s3[(l >> 8) & 0xFF];
431  t += context->s4[l & 0xFF];
432  r ^= t;
433 
434  //Apply even round function
435  r ^= context->p[i + 1];
436  t = context->s1[(r >> 24) & 0xFF];
437  t += context->s2[(r >> 16) & 0xFF];
438  t ^= context->s3[(r >> 8) & 0xFF];
439  t += context->s4[r & 0xFF];
440  l ^= t;
441  }
442 
443  //The rounds are followed by two final XOR's with the last elements of
444  //the P-array
445  l ^= context->p[16];
446  r ^= context->p[17];
447 
448  //Recombine L and R
449  STORE32BE(r, output + 0);
450  STORE32BE(l, output + 4);
451 }
452 
453 
454 /**
455  * @brief Decrypt a 8-byte block using Blowfish algorithm
456  * @param[in] context Pointer to the Blowfish context
457  * @param[in] input Ciphertext block to decrypt
458  * @param[out] output Plaintext block resulting from decryption
459  **/
460 
461 void blowfishDecryptBlock(BlowfishContext *context, const uint8_t *input,
462  uint8_t *output)
463 {
464  uint_t i;
465  uint32_t l;
466  uint32_t r;
467  uint32_t t;
468 
469  //Divide the ciphertext into two 32-bit halves (L and R)
470  r = LOAD32BE(input + 0);
471  l = LOAD32BE(input + 4);
472 
473  //16 rounds of computation are needed
474  for(i = 16; i > 0; i -= 2)
475  {
476  //Apply even round function
477  r ^= context->p[i + 1];
478  t = context->s1[(r >> 24) & 0xFF];
479  t += context->s2[(r >> 16) & 0xFF];
480  t ^= context->s3[(r >> 8) & 0xFF];
481  t += context->s4[r & 0xFF];
482  l ^= t;
483 
484  //Apply odd round function
485  l ^= context->p[i];
486  t = context->s1[(l >> 24) & 0xFF];
487  t += context->s2[(l >> 16) & 0xFF];
488  t ^= context->s3[(l >> 8) & 0xFF];
489  t += context->s4[l & 0xFF];
490  r ^= t;
491  }
492 
493  //The rounds are followed by two final XOR's with the first elements of
494  //the P-array
495  r ^= context->p[1];
496  l ^= context->p[0];
497 
498  //Recombine L and R
499  STORE32BE(l, output + 0);
500  STORE32BE(r, output + 4);
501 }
502 
503 
504 /**
505  * @brief XOR data block with random salt
506  * @param[in,out] data Pointer the data block (16 bytes)
507  * @param[in] salt Pointer to the random salt (16 bytes)
508  * @param[in] saltLen Length of the salt, in bytes
509  * @param[in,out] saltIndex Current salt index
510  **/
511 
512 void blowfishXorBlock(uint8_t *data, const uint8_t *salt, size_t saltLen,
513  size_t *saltIndex)
514 {
515  size_t i;
516  size_t n;
517 
518  //The salt parameter is optional
519  if(saltLen > 0)
520  {
521  //Get current salt index
522  n = *saltIndex;
523 
524  //XOR the data block with the random salt
525  for(i = 0; i < BLOWFISH_BLOCK_SIZE; i++)
526  {
527  //Perform XOR operation
528  data[i] ^= salt[n];
529 
530  //Treat the salt as cyclic
531  if(++n >= saltLen)
532  {
533  n = 0;
534  }
535  }
536 
537  //Save current salt index
538  *saltIndex = n;
539  }
540 }
541 
542 
543 /**
544  * @brief Release Blowfish context
545  * @param[in] context Pointer to the Blowfish context
546  **/
547 
549 {
550  //Clear Blowfish context
551  osMemset(context, 0, sizeof(BlowfishContext));
552 }
553 
554 #endif
void(* CipherAlgoEncryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1009
#define LOAD32BE(p)
Definition: cpu_endian.h:210
uint32_t s3[256]
Definition: blowfish.h:57
@ CIPHER_ALGO_TYPE_BLOCK
Definition: crypto.h:953
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t data[]
Definition: ethernet.h:222
uint32_t p[18]
Definition: blowfish.h:54
error_t blowfishInitState(BlowfishContext *context)
Blowfish state initialization.
Definition: blowfish.c:257
error_t blowfishExpandKey(BlowfishContext *context, const uint8_t *salt, size_t saltLen, const uint8_t *key, size_t keyLen)
Key expansion.
Definition: blowfish.c:291
uint32_t s4[256]
Definition: blowfish.h:58
uint32_t s1[256]
Definition: blowfish.h:55
uint8_t r
Definition: ndp.h:346
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
void blowfishDeinit(BlowfishContext *context)
Release Blowfish context.
Definition: blowfish.c:548
error_t
Error codes.
Definition: error.h:43
void(* CipherAlgoDecryptBlock)(void *context, const uint8_t *input, uint8_t *output)
Definition: crypto.h:1012
error_t blowfishInit(BlowfishContext *context, const uint8_t *key, size_t keyLen)
Initialize a Blowfish context using the supplied key.
Definition: blowfish.c:227
@ ERROR_INVALID_KEY_LENGTH
Definition: error.h:107
General definitions for cryptographic algorithms.
Blowfish encryption algorithm.
error_t(* CipherAlgoInit)(void *context, const uint8_t *key, size_t keyLen)
Definition: crypto.h:1000
void blowfishEncryptBlock(BlowfishContext *context, const uint8_t *input, uint8_t *output)
Encrypt a 8-byte block using Blowfish algorithm.
Definition: blowfish.c:411
uint8_t l
Definition: ndp.h:412
uint8_t n
Blowfish algorithm context.
Definition: blowfish.h:53
const CipherAlgo blowfishCipherAlgo
Definition: blowfish.c:204
uint8_t value[]
Definition: tcp.h:369
Common interface for encryption algorithms.
Definition: crypto.h:1068
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:135
void(* CipherAlgoDeinit)(void *context)
Definition: crypto.h:1015
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 8-byte block using Blowfish algorithm.
Definition: blowfish.c:461
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
void blowfishXorBlock(uint8_t *data, const uint8_t *salt, size_t saltLen, size_t *saltIndex)
XOR data block with random salt.
Definition: blowfish.c:512
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.