fwutil/src/blowfish.c
2025-02-08 21:02:41 -06:00

310 lines
17 KiB
C

#include "blowfish.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
static const BfBlowfishContext sInitTable = {
{
0x5f20d599, 0xb9f54457, 0xd9a4196e, 0x945a6a9e, 0xebf1aed8, 0x3ae27541, 0x32d08293, 0xd531ee33,
0x9a6157cc, 0x1ba20637, 0xf5723979, 0xbef6ae55, 0xfb691b5f, 0xe9f19de5, 0xa1d92cce, 0xe605325e,
0xcffed3fe, 0x0d0462d4
},
{
{
0xb7ecf58b, 0xbb79602b, 0x0d319512, 0x2bda3f6e, 0xf1f08488, 0x257e123d, 0xbbf12245, 0x061a0624,
0x28dfad11, 0x3481648b, 0x2933eb2b, 0xbdf2aa99, 0x9d95149c, 0x8cf5f79f, 0x29a19772, 0xcf5fd19d,
0x1a074d66, 0x4b4ad3de, 0xa3a7c985, 0x3a059517, 0xbf0a493d, 0xa28b890a, 0xdd49824a, 0x0bf19027,
0x6a1cebe9, 0x05457683, 0x617081ba, 0xde4b3f17, 0x39abcfae, 0x563af257, 0x8aad1148, 0x3f45e140,
0x54029bfa, 0xfb93a6ca, 0x6ffe4def, 0x9c87d8a3, 0x48d5ba08, 0xfd2d8d6a, 0x74f8156e, 0x8b52bebd,
0x9e8a2218, 0x073774fb, 0x4a6c361b, 0x6242ba19, 0x109179b9, 0x9665677b, 0xe82302fe, 0x778c99ee,
0x64865c3e, 0x86786d4d, 0xe2654fa5, 0x5adfb21e, 0x087ed00a, 0xac71b014, 0x1c83dbbd, 0x62a1d7b9,
0x7c63c6cd, 0xe6c36952, 0x12ce75bf, 0x04215d44, 0x3cd3fbfa, 0xd4631138, 0x49418595, 0x08f20946,
0x1fdc1143, 0x6d15c076, 0x70633c1f, 0x6c8087ea, 0x8b63bdc3, 0x372137c2, 0x2309eedc, 0x4d6a372e,
0x50f79073, 0x921cac30, 0x91231004, 0xaa07d24f, 0x9a4f3e68, 0x6a6064c9, 0xf32114c8, 0x124122d6,
0xe6cf2444, 0x0ddd568a, 0x85e14d53, 0x5a528c1e, 0xc284199c, 0x6ff15703, 0x58be00e3, 0xd5ed4cf6,
0x1f9c6421, 0x3c0355be, 0xaaffdc4a, 0x5de0dac9, 0xdee6bf5e, 0xf8b1d8f5, 0xb9b336ff, 0xdb956762,
0xed375f31, 0x9967704c, 0x3118b590, 0x99993d6c, 0xd3da42e4, 0xa0134225, 0x6c70d7ae, 0xc7cf55b1,
0x43d546d7, 0x443d1761, 0x8533e928, 0x93a2d0d5, 0x1f1225aa, 0x460bc5fb, 0x567697f5, 0x87bea645,
0xe86b94b1, 0x9933feb1, 0x6c3e1fae, 0x091d7139, 0xe4379000, 0x74753e10, 0x3b838cff, 0xf9b0f1b0,
0x42470501, 0xacd6f195, 0x9ee6387e, 0x3f267495, 0x185068b4, 0xb43043d0, 0x68e34b4c, 0xb64de5bf,
0xa00a8b95, 0x77322574, 0x2cf7a1cf, 0x5a1371d8, 0x51c9eaab, 0xefee0de8, 0x197e93e9, 0x38431ea7,
0xa12c1681, 0xcc73e348, 0xd36c2129, 0xd9a0ce5d, 0xa0437161, 0x64b51315, 0x192acf92, 0xa5b7addc,
0xf865869f, 0xfbe79f1a, 0x13b8fdf7, 0x6fdb276c, 0xf71c35df, 0x9b5b2c8d, 0x6438ab12, 0x31decc06,
0x11754ee8, 0xeafae364, 0xc25434eb, 0xeb343fad, 0x267d2c93, 0xf3569d36, 0xb3f6e15a, 0x9e4a6398,
0x9ae48332, 0x907d6084, 0xee0e132e, 0xa2364b93, 0x3816ec85, 0x020688e8, 0x3aa0f0bf, 0x9a6ad7ed,
0xcf57e173, 0xdcb844f8, 0xd159232e, 0x715295df, 0x4ba06199, 0x786e7fd5, 0x30c5a9ba, 0x328640d3,
0x9c0c329d, 0x2f02b737, 0xa99854ba, 0xc90413c4, 0xe7c8be8d, 0x2e50975d, 0x5922d693, 0x22bc270c,
0x20a7e092, 0x7f6f930f, 0xb5d39f4c, 0x740b2aa6, 0x107d4967, 0xc5d1cb26, 0x8ce77186, 0x5be99ca0,
0x01f61ab2, 0x5e9e8cee, 0xdb1af283, 0x84eae5e6, 0x7cd27659, 0x49a58df6, 0x16c24836, 0xa383bb52,
0x0c07b974, 0x2861ff3b, 0xe4e961e1, 0xaa156eef, 0x5de8ba4e, 0x32bb9605, 0x72fbb056, 0xc80e0f52,
0x76652542, 0xdef2af89, 0x01f02710, 0x97a7744b, 0x5426d507, 0x821f0954, 0x307d860a, 0x26b30e39,
0xbb570b9b, 0xaf310636, 0xd9fc79fd, 0x0c2b1030, 0xd79be1b3, 0xef5fdc7b, 0x4513f8d2, 0xbd75474d,
0x7e3c9646, 0xb53ef375, 0x3b9ac567, 0x6b295bb0, 0xc85b80de, 0x31b10515, 0xdd49ceb6, 0xaeb584ad,
0x3167dc60, 0x4efe3034, 0xa62f80bd, 0x213963bf, 0x7f35d986, 0x05226816, 0x2690e954, 0x516c078c,
0xd75531a4, 0x3ea80709, 0xc166532e, 0xc47bf2f8, 0xf1cf58f2, 0xe7a2c587, 0x87308f27, 0x6264a058,
0x88b91823, 0xc4cefa7c, 0x17adae98, 0xf35b4acc, 0x56d548e9, 0xc8f20dd3, 0xdb8c7392, 0xac562fd7
}, {
0x6992f981, 0xf632c64d, 0x218dc0e6, 0x618076e2, 0x6cdcbc11, 0x6919af93, 0xb9bfd09b, 0x67029f31,
0x83ee51a3, 0x0c7b2206, 0x404249ab, 0x7d01d5b8, 0x55f75ece, 0x99c53953, 0x9f87d846, 0xb464f7ba,
0xa1fa9ae3, 0x1068906d, 0x548aca30, 0xc3609fa7, 0x0d6bf519, 0xe698517a, 0xb4514398, 0x4fe935d6,
0x7b0fdfc3, 0xbd5c2fd6, 0x1961153a, 0xaacb4bf1, 0xc9646ddc, 0x561ec6d3, 0x504c38ef, 0xcc758671,
0xe94e0d0d, 0x5d06f628, 0xd3aa1b70, 0x39a8cf45, 0x2ea695ac, 0xd422e4b4, 0x5f37a874, 0xcc047a48,
0xd8404ca5, 0x0828b428, 0x52721c0d, 0x477df041, 0x4e533a19, 0x6b628458, 0x818ab593, 0xdc0d4e21,
0xc6a23fb4, 0x402bc9fc, 0xe90438da, 0x6b865a5e, 0x8525220c, 0x7c8d1168, 0x55951d92, 0xbb8eab4d,
0xb7e6a6da, 0x5a32b651, 0x05dd4105, 0x50560a2a, 0xcc471791, 0xb57ee6c9, 0x73db4a61, 0x33c85167,
0x746edaf5, 0x37c3542e, 0x08af6d0d, 0x5f8a15e8, 0xcd2159e2, 0x060cdea8, 0x5f6b775a, 0x3e6518db,
0x78de50c8, 0xb382b8e0, 0x32724e5d, 0x34c14f07, 0xb796ba23, 0x28a44e67, 0xeb62341e, 0xe9706a2d,
0x70c4422f, 0x9c315a4e, 0x28475bf9, 0x6f71daaa, 0x78b31f38, 0x1c6b92c4, 0x9a35f69e, 0xbf0e4db7,
0x412918cc, 0x5d354803, 0xc62bd055, 0x605caf29, 0x5e8e6974, 0xbdd47c9b, 0x7d64447b, 0x695d923f,
0x4b001fb6, 0xcf3583d4, 0x174e647e, 0x2ed58dae, 0x4e12289a, 0x08492b2e, 0x46c6ae5c, 0x6141ae85,
0xd2826f1e, 0x1f163751, 0xa459f60b, 0xaf5aca9a, 0x8b33d40d, 0x84f16320, 0xcfcb5c80, 0xd3b9b408,
0x62bd0516, 0x569b3183, 0xba9f9851, 0xb2aa5bb2, 0xb52c6b22, 0x63fa48d4, 0xfa585f2b, 0x0964fa61,
0xb8e038bb, 0xa860929d, 0x0e6f670d, 0x010df537, 0xd477c29f, 0x73f1ecfe, 0x7de03930, 0xe49861f5,
0x0455282c, 0x2fdb5556, 0x58e5ec6b, 0x8064b606, 0x4e1a2a6a, 0xc4d80f5b, 0x19522e0a, 0x30f562d9,
0x7b8cbe48, 0xa29b384f, 0xd3c9afc3, 0x4162c1c7, 0x2161b986, 0x4f996f57, 0x7bcebac1, 0x5e4d3bb5,
0x57448b8a, 0x705f135f, 0x47295b6d, 0xece238dc, 0x12655504, 0x4317e82a, 0x2add8ee1, 0xf794e2b3,
0xe65c6e09, 0x6df88aeb, 0x48544989, 0xbfad2ff5, 0xca4b94ea, 0x828739fc, 0xf2018a5f, 0x71e6f275,
0xde42d8d6, 0x281d2df1, 0xa37e88a6, 0x301d47a0, 0xdf71a3d9, 0x01cb1c49, 0xf2b136f8, 0x5d5822f0,
0xa0bd6b45, 0x4288b2bb, 0xce288cc7, 0x6390e893, 0x897c9008, 0xb77df53c, 0x554f2d04, 0x7efd1651,
0xc1bee879, 0xf8d412f2, 0x230584b4, 0x2bd2cca0, 0xadabe1fd, 0x6c55d10d, 0x4d944123, 0x054f3777,
0x17bf0c28, 0x6c6712b3, 0xf75ac38c, 0x6d2a8441, 0x271294d0, 0x9cedb42c, 0x8247ec4d, 0xb967d597,
0x55c09d1b, 0x8ee57e07, 0x3ee7a8e2, 0x3a0ee412, 0x3455452a, 0x5a2df9a2, 0x7c52ab1b, 0x555f1083,
0x435af1d2, 0xa4a7c62b, 0xe8951589, 0xf89d4bb4, 0x609fe375, 0xe6d65b78, 0x21e6440d, 0x2247bd06,
0xad00a453, 0x8513438d, 0xfcaaf739, 0xed7baf38, 0x542be4fc, 0xfc4c9850, 0xdff78085, 0xe122803c,
0x24deda94, 0x397ab0c6, 0xa10fdc38, 0x6ff9f4a7, 0x8b571863, 0x2e2a4184, 0xd9f253d4, 0xddd00f00,
0xa6196e99, 0x5becd00a, 0xc0ab2458, 0xec6506cb, 0x9438131a, 0x2f03670a, 0x77e3f73f, 0xc6337744,
0xe3d03914, 0x7908a2c0, 0x579940bb, 0x90010b41, 0x48cce1cd, 0xafb3db67, 0x4cf37488, 0xb1728f82,
0xc42923b5, 0xfc196c12, 0x9ca4468e, 0x876525c4, 0x8abe6dd3, 0x38031193, 0xf32b83ed, 0xea93a446,
0x1d85533b, 0x08f1d4ce, 0xfced2783, 0xbc181a9b, 0xdcae8bf9, 0x3850ab24, 0x104b72e9, 0x467b1722
}, {
0x6459ab5d, 0xf8ae40f3, 0xf9c8e5bb, 0x554e0326, 0xfeebeb7d, 0xe0e639f7, 0x2ebe110a, 0xed98ff28,
0x5642c9c0, 0x00fdc342, 0xa287aff6, 0x323f015b, 0x9a954792, 0x3d32a572, 0x9bd06bae, 0x9249d207,
0xfa4a78e3, 0xf27d06a1, 0x7477cf41, 0x0cb21404, 0x16648486, 0xa151bbd5, 0xd1f16fe5, 0x5ff7e2f2,
0xb84d2058, 0xddcfc757, 0x76bed8c5, 0x7e5ff63d, 0x888b2ae7, 0x3f381b24, 0x7723410e, 0xd44bf0f5,
0xa4fa1f0c, 0xcf5f800b, 0xdae0f645, 0x5359342f, 0x523c20fb, 0xb5355e62, 0x608bfe62, 0x5a86e363,
0xd16e1a15, 0x32bc4547, 0x3867ebb4, 0x336ee4ab, 0xa3edb53a, 0x4ee067ad, 0x62ee9541, 0x1d267162,
0x3062ef31, 0xac82d7af, 0x0405dcc2, 0xbf0797f5, 0x07235911, 0xe80264c0, 0xaf3ee597, 0xa659ac18,
0x90334a8b, 0x9c7c6e1c, 0x3c4c7e20, 0xbb64613e, 0x7e7c6bc5, 0x4cc59f3e, 0xf573ea9f, 0x4cc089d7,
0x2df4fbf4, 0x511b14ec, 0xc812c1d5, 0x4a0bdf10, 0x93bc9c8b, 0x3e3e6a45, 0xbaa9c17d, 0x07b4c1cd,
0x8668e1e4, 0x386db243, 0x5c0cfbf3, 0xde713766, 0xa06eef56, 0xa7654010, 0xbed0f798, 0x3637c80e,
0x7cca10ec, 0x1e84ab9c, 0x02761705, 0xaa524f1c, 0xa0c6c15f, 0x04d8b956, 0xa74d4484, 0x60ded859,
0x050e38e6, 0x3be1038f, 0x3304816d, 0xce0b306f, 0x33210569, 0x89bb26fb, 0x87aeb67d, 0xe007517e,
0x0a96f7ac, 0x5cc4f96b, 0x4744e41d, 0xe3fa5eb8, 0x42558478, 0xf75e484b, 0x8635477d, 0x05432b1d,
0xb88aec03, 0x763c061e, 0x431a480c, 0xed8ab7a7, 0x43c6131e, 0xdbef10ee, 0x833cfbec, 0xef4495b2,
0x4e5154d8, 0x1d44112d, 0x1e5936fb, 0xc3c1347a, 0x610057ca, 0x16a567ea, 0x55d0559b, 0x36d97fe1,
0xae7640d2, 0xb0ce01dc, 0xcbd5837a, 0x6bec9820, 0x349272c1, 0x375782f3, 0x36328a62, 0xae43900c,
0x789b5cae, 0x0265138e, 0xc17168fd, 0xa031b0fe, 0xc3b08224, 0xa76979b1, 0xd0ebd2f5, 0xdc32c082,
0x3c26c79e, 0xc1988d6d, 0xd0d422bb, 0x3eec330f, 0xdce1ccb9, 0x36774c6a, 0xbff91c14, 0x5f289f81,
0x29328571, 0xc4487590, 0xd8ce4ab3, 0x2f148f44, 0xef5740fd, 0xd97508aa, 0x6ed6d146, 0xc31f5532,
0x1f84fe18, 0xffd584fc, 0x481b5e71, 0x0e9586c3, 0xd3270828, 0x7b718338, 0x5463804c, 0xacb0569a,
0x31ca80cf, 0xf3feef09, 0x7e24afbe, 0x3f53fea6, 0x334a8dc2, 0xa622d168, 0xea7bad66, 0xb043b6de,
0x009525a1, 0x46753fa3, 0xec441114, 0x92bc95d7, 0x16a94ff0, 0x60976253, 0xf1410f2a, 0xeebe2471,
0xcd087f94, 0x85b39360, 0x3f00075b, 0x83280fd8, 0x9f69d19a, 0xc32edad1, 0xb9a20190, 0x662a4e6b,
0xa6aeda9d, 0x68d32aea, 0x9c0c0c2f, 0xed4a8cd2, 0x65579ee2, 0xa387099d, 0x5d32c4b4, 0x2b32d4c9,
0x1e71e0b1, 0x90e64d64, 0x401ee371, 0x84f37ded, 0x78c8ed0e, 0x71c0ae76, 0x05bb7227, 0xfb6402ea,
0xb56b48f3, 0xed3f9342, 0xd253139f, 0xec2afef7, 0xdb25471d, 0xc686913c, 0xfd11f08e, 0xf7367423,
0x7a9ef5a4, 0x4450537e, 0xd3ca47d4, 0xe66d38eb, 0x7f9471d9, 0x4b69c64a, 0xea52f411, 0xb08afe22,
0x598b6736, 0x2a80e6e8, 0x130465eb, 0x9edcecee, 0x05ecb15f, 0x9fe6596a, 0x896b595e, 0xca1af7bf,
0x6a5bf944, 0xe4038571, 0x70e06229, 0xcfc4416f, 0xe3ccb1b2, 0xa807a67e, 0x847fe787, 0x4b52db93,
0xdd7eec6c, 0x104824d4, 0x60049f69, 0x1848e674, 0xb92ce4f3, 0x7a502e4f, 0x6954d4df, 0xf3a78b2b,
0xf31fffce, 0x3901263e, 0x89849517, 0x4b4cf0b0, 0xc49f9182, 0xa59dac4b, 0x2517af74, 0xd332cac9,
0x848a89bc, 0xae0dcc89, 0x9cdba27c, 0xee91786a, 0x4e5d76ea, 0x69f56087, 0x02d46715, 0x3648afcf
}, {
0x6fbfea07, 0x8f062d66, 0xf9fe9ac4, 0x758790f6, 0x0fadf7b8, 0x3d5a1076, 0xb32eb059, 0xcc2c35c7,
0xcb2b5670, 0xc59637e3, 0x8a1b462f, 0x88c74622, 0x983226a7, 0x2286df61, 0x2f1cf48a, 0xaa09a187,
0xd3aea9cc, 0x1c4500bd, 0x8687549a, 0xffef8752, 0x8fa18f1e, 0x355c89c1, 0x3a2dda1b, 0xc2b2162c,
0x78e256f1, 0x97636bc1, 0xc98f56c5, 0xaa2c7f32, 0xaca8a6af, 0x88229120, 0x8b60e4de, 0x25424bf9,
0x9c7fe31a, 0x3a89192c, 0x36d4057e, 0xc25869cc, 0x2f8b32c1, 0x7aeb8590, 0xa1a55039, 0x66c59227,
0x584f20b0, 0x4383557e, 0x9ce2452b, 0x9012d8e4, 0x5683162c, 0xb3037916, 0x18612dad, 0x371f131a,
0x739ce1e2, 0xfdd5807b, 0xfc87512d, 0x1fd7aa7b, 0xaf8e7a2c, 0xcdbb8df4, 0x727c1195, 0xe26fee0b,
0x37deafb9, 0x8d8cde83, 0xb7670562, 0x568dc696, 0x62d70db6, 0x3646d6ba, 0xe6c88ebd, 0x106c2aea,
0x5b6bff14, 0x463c82fa, 0x464330b1, 0x9b7d8a51, 0x79833e92, 0xb25d555b, 0x90ce5e6c, 0x98538e62,
0xe56d0dc9, 0xc5cd572d, 0xe1ba5781, 0x728fb8e8, 0xdc134fe5, 0x15719dea, 0x8811b210, 0x7fd409d5,
0x2c7f655b, 0x114c383b, 0xfb8d5068, 0xbf59b09e, 0x4a898094, 0x12181ac5, 0x4ad15389, 0x8ce82910,
0xeab6ec1c, 0x8b17c746, 0xa8311525, 0xb1436ba2, 0x0bdbe29d, 0x11b09b87, 0xd2710e04, 0x82897729,
0x7f41660a, 0xff480b1d, 0xfd24bb72, 0x9ba148c2, 0xce7f7bfe, 0xd986db88, 0xb01c3b85, 0x0733a8dc,
0xe32e51bf, 0x97009a0e, 0x97c0061e, 0xb6d89d43, 0x6786c445, 0x88f8005f, 0x9e52a49a, 0x838aaac7,
0x18c5ec75, 0x2fc3ceae, 0x18f92b1a, 0xf51aaeff, 0x33b50b53, 0xe8fda751, 0x64a2e1a8, 0x431722b6,
0xd80acc80, 0x40ba3bae, 0x4a92d9d7, 0x1004df89, 0x2b189bee, 0x8a69776a, 0xb9f9f468, 0x6e1521a2,
0x033b1ee6, 0x609b3062, 0x9b257e41, 0x52c58f9e, 0xc2f80810, 0x1121a169, 0x795e3788, 0x10ff6635,
0xed6e1842, 0x1c6bb697, 0x6de5364e, 0xbfe4b47d, 0x05e0b920, 0xb8d5693a, 0xe0dcd5e3, 0x3e53acb9,
0xad57a407, 0x1848ff77, 0x49ac2a76, 0x75478e2a, 0x63679f6d, 0x398c3530, 0x6fd53905, 0xad5b3a64,
0x82bb0bca, 0xb1459952, 0x99363693, 0x442013af, 0x4402d836, 0x85923909, 0x974a4aff, 0xd763a687,
0x24b5b5c7, 0x6fb40fed, 0x1452580c, 0xd37ba6d9, 0x5838bc79, 0x843bbda1, 0x061ad806, 0xeaa86bfd,
0x0428694b, 0x9982ad37, 0x851b0efb, 0x735da8bd, 0x7558dccd, 0x6c63be0a, 0xe44ce748, 0x60042b30,
0xdad815b9, 0x8f758186, 0x1c8dd496, 0x7c85705d, 0xd57b671c, 0xcea66708, 0x70660a4b, 0xd463e5b7,
0xea828a5b, 0xe2ca6710, 0x8517eff4, 0x8a5f2a2f, 0x6af88297, 0xea1034d6, 0x3c5cc9eb, 0x46f849e1,
0xf6bddeeb, 0xaaf192a9, 0xb018a0a6, 0x1f0fd33a, 0x31ff6ff3, 0xd3444345, 0x88f79a50, 0xcec19609,
0x2cf2cc76, 0x82adba2c, 0x84188f77, 0x9c07d2c0, 0x4e839036, 0x434fa50b, 0x78ab043e, 0x09fbd64f,
0xda902401, 0x613a3c6f, 0x4a697f0d, 0x02302beb, 0x84e0dbb4, 0x35d7eca9, 0x857d37bf, 0x4ea9ce58,
0xa8c780e4, 0x486730d3, 0x2faf29eb, 0xa7b46a74, 0x923f0f3f, 0xaccaf3af, 0x94d94baf, 0x81ca43c0,
0xa1482f0d, 0xd2d527b0, 0x85054bef, 0x934ddea3, 0xbbf03c30, 0x27308f4a, 0x3ee3eb4c, 0x2f9aed64,
0xf082f13b, 0x7fcff4ba, 0xe1b0cb40, 0x57aabc7f, 0xf274c9d3, 0x220d43fa, 0x4e77f4d0, 0x7085d793,
0xb6bf991f, 0x30f135de, 0xf0715ea7, 0x7b2d016b, 0x5333f064, 0xf388390a, 0x6ba63a6b, 0x432fd235,
0xb5fd02cd, 0xaa5bbce9, 0x7e19a4d8, 0x81945d0e, 0xad776f9e, 0x93740ed6, 0x18c4e796, 0x19f5ad5f
}
}
};
static void SwapInts(uint32_t *p1, uint32_t *p2) {
uint32_t temp = *p1;
*p1 = *p2;
*p2 = temp;
}
static uint32_t F(BfBlowfishContext *ctx, uint32_t x) {
uint32_t y = 0;
y ^= ctx->sbox[0][(x >> 24) & 0xFF];
y += ctx->sbox[1][(x >> 16) & 0xFF];
y ^= ctx->sbox[2][(x >> 8) & 0xFF];
y += ctx->sbox[3][(x >> 0) & 0xFF];
return y;
}
static void BfEncryptBlock(BfBlowfishContext *ctx, uint32_t *xl, uint32_t *xr) {
uint32_t Xl = *xl;
uint32_t Xr = *xr;
for (int i = 0; i < 16; i++) {
Xl ^= ctx->parr[i];
Xr ^= F(ctx, Xl);
SwapInts(&Xl, &Xr);
}
*xl = Xr ^ ctx->parr[17];
*xr = Xl ^ ctx->parr[16];
}
static void BfDecryptBlock(BfBlowfishContext *ctx, uint32_t *xl, uint32_t *xr) {
uint32_t Xl = *xl;
uint32_t Xr = *xr;
for (int i = 17; i > 1; i--) {
Xl ^= ctx->parr[i];
Xr ^= F(ctx, Xl);
SwapInts(&Xl, &Xr);
}
*xl = Xr ^ ctx->parr[0];
*xr = Xl ^ ctx->parr[1];
}
void BfCtxInit(BfBlowfishContext *ctx, const unsigned char *key, unsigned int keylen) {
unsigned int k = 0;
for (int i = 0; i < 18; i++) {
ctx->parr[i] ^= key[(k++) % keylen] << 24;
ctx->parr[i] ^= key[(k++) % keylen] << 16;
ctx->parr[i] ^= key[(k++) % keylen] << 8;
ctx->parr[i] ^= key[(k++) % keylen] << 0;
}
uint32_t l = 0, r = 0;
for (int i = 0; i < 9; i++) {
BfEncryptBlock(ctx, &l, &r);
ctx->parr[i * 2 + 0] = l;
ctx->parr[i * 2 + 1] = r;
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 128; j++) {
BfEncryptBlock(ctx, &l, &r);
ctx->sbox[i][j * 2 + 0] = l;
ctx->sbox[i][j * 2 + 1] = r;
}
}
}
static void BfCtxMixKey(BfBlowfishContext *ctx, uint32_t *keyBufp, uint32_t keylen) {
BfEncryptBlock(ctx, keyBufp + 2, keyBufp + 1);
BfEncryptBlock(ctx, keyBufp + 1, keyBufp + 0);
BfCtxInit(ctx, (unsigned char *) keyBufp, keylen);
}
static void BfCtxInitWithKey(BfBlowfishContext *ctx, uint32_t key, const unsigned char *fwHeader) {
memcpy(ctx, &sInitTable, sizeof(BfBlowfishContext));
uint32_t keyBufp[3];
keyBufp[0] = key;
keyBufp[1] = key >> 1;
keyBufp[2] = key << 1;
BfCtxMixKey(ctx, keyBufp, 12);
const uint32_t *blowfishedKeyp = (const uint32_t *) (fwHeader + 0x18);
uint32_t keycpy[2];
memcpy(keycpy, blowfishedKeyp, sizeof(keycpy));
BfDecryptBlock(ctx, keycpy + 1, keycpy + 0);
BfCtxMixKey(ctx, keyBufp, 12);
}
void BfDecrypt(unsigned char *buf, unsigned int len, const unsigned char *fwHeader) {
//init blowfish
BfBlowfishContext ctx;
BfCtxInitWithKey(&ctx, *(const uint32_t *) (fwHeader + 0x8), fwHeader);
for (unsigned int i = 0; i < len / 8; i++) {
uint32_t *p = (uint32_t *) (buf + i * 8);
BfDecryptBlock(&ctx, p + 1, p + 0);
}
}
void BfEncrypt(unsigned char *buf, unsigned int len, const unsigned char *fwHeader) {
//init blowfish
BfBlowfishContext ctx;
BfCtxInitWithKey(&ctx, *(const uint32_t *) (fwHeader + 0x8), fwHeader);
for (unsigned int i = 0; i < len / 8; i++) {
uint32_t *p = (uint32_t *) (buf + i * 8);
BfEncryptBlock(&ctx, p + 1, p + 0);
}
}
BfStream *BfDecryptStreamInit(const unsigned char *buffer, unsigned int len, const unsigned char *fwHeader) {
BfStream *stream = (BfStream *) calloc(1, sizeof(BfStream));
stream->buffer = buffer;
stream->size = len;
stream->srcpos = 0;
stream->error = 0;
BfCtxInitWithKey(&stream->ctx, *(const uint32_t *) (fwHeader + 0x8), fwHeader);
return stream;
}
unsigned char BfDecryptStreamNext(BfStream *stream) {
unsigned int blockpos = stream->srcpos & 7;
if (blockpos == 0) {
//check bounds on next fetch
if ((stream->size - stream->srcpos) < 8) {
stream->error = 1;
return 0xFF;
}
//blockpos==0: fetch next block
stream->block[0] = (stream->buffer[stream->srcpos + 0] << 0)
| (stream->buffer[stream->srcpos + 1] << 8)
| (stream->buffer[stream->srcpos + 2] << 16)
| (stream->buffer[stream->srcpos + 3] << 24);
stream->block[1] = (stream->buffer[stream->srcpos + 4] << 0)
| (stream->buffer[stream->srcpos + 5] << 8)
| (stream->buffer[stream->srcpos + 6] << 16)
| (stream->buffer[stream->srcpos + 7] << 24);
BfDecryptBlock(&stream->ctx, stream->block + 1, stream->block + 0);
}
stream->srcpos++;
return (stream->block[blockpos / 4] >> ((blockpos & 3) * 8)) & 0xFF;
}
void BfDecryptStreamEnd(BfStream *stream) {
//nothing
free(stream);
}