1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * BF low level APIs are deprecated for public use, but still ok for internal 12e1051a39Sopenharmony_ci * use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <openssl/blowfish.h> 17e1051a39Sopenharmony_ci#include "bf_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci/* 20e1051a39Sopenharmony_ci * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From 21e1051a39Sopenharmony_ci * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE 22e1051a39Sopenharmony_ci * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) 23e1051a39Sopenharmony_ci */ 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) 26e1051a39Sopenharmony_ci# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ 27e1051a39Sopenharmony_cito modify the code. 28e1051a39Sopenharmony_ci#endif 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_civoid BF_encrypt(BF_LONG *data, const BF_KEY *key) 31e1051a39Sopenharmony_ci{ 32e1051a39Sopenharmony_ci register BF_LONG l, r; 33e1051a39Sopenharmony_ci register const BF_LONG *p, *s; 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ci p = key->P; 36e1051a39Sopenharmony_ci s = &(key->S[0]); 37e1051a39Sopenharmony_ci l = data[0]; 38e1051a39Sopenharmony_ci r = data[1]; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci l ^= p[0]; 41e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[1]); 42e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[2]); 43e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[3]); 44e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[4]); 45e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[5]); 46e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[6]); 47e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[7]); 48e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[8]); 49e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[9]); 50e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[10]); 51e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[11]); 52e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[12]); 53e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[13]); 54e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[14]); 55e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[15]); 56e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[16]); 57e1051a39Sopenharmony_ci# if BF_ROUNDS == 20 58e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[17]); 59e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[18]); 60e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[19]); 61e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[20]); 62e1051a39Sopenharmony_ci# endif 63e1051a39Sopenharmony_ci r ^= p[BF_ROUNDS + 1]; 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci data[1] = l & 0xffffffffU; 66e1051a39Sopenharmony_ci data[0] = r & 0xffffffffU; 67e1051a39Sopenharmony_ci} 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_civoid BF_decrypt(BF_LONG *data, const BF_KEY *key) 70e1051a39Sopenharmony_ci{ 71e1051a39Sopenharmony_ci register BF_LONG l, r; 72e1051a39Sopenharmony_ci register const BF_LONG *p, *s; 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci p = key->P; 75e1051a39Sopenharmony_ci s = &(key->S[0]); 76e1051a39Sopenharmony_ci l = data[0]; 77e1051a39Sopenharmony_ci r = data[1]; 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci l ^= p[BF_ROUNDS + 1]; 80e1051a39Sopenharmony_ci# if BF_ROUNDS == 20 81e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[20]); 82e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[19]); 83e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[18]); 84e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[17]); 85e1051a39Sopenharmony_ci# endif 86e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[16]); 87e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[15]); 88e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[14]); 89e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[13]); 90e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[12]); 91e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[11]); 92e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[10]); 93e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[9]); 94e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[8]); 95e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[7]); 96e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[6]); 97e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[5]); 98e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[4]); 99e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[3]); 100e1051a39Sopenharmony_ci BF_ENC(r, l, s, p[2]); 101e1051a39Sopenharmony_ci BF_ENC(l, r, s, p[1]); 102e1051a39Sopenharmony_ci r ^= p[0]; 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci data[1] = l & 0xffffffffU; 105e1051a39Sopenharmony_ci data[0] = r & 0xffffffffU; 106e1051a39Sopenharmony_ci} 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_civoid BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 109e1051a39Sopenharmony_ci const BF_KEY *schedule, unsigned char *ivec, int encrypt) 110e1051a39Sopenharmony_ci{ 111e1051a39Sopenharmony_ci register BF_LONG tin0, tin1; 112e1051a39Sopenharmony_ci register BF_LONG tout0, tout1, xor0, xor1; 113e1051a39Sopenharmony_ci register long l = length; 114e1051a39Sopenharmony_ci BF_LONG tin[2]; 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci if (encrypt) { 117e1051a39Sopenharmony_ci n2l(ivec, tout0); 118e1051a39Sopenharmony_ci n2l(ivec, tout1); 119e1051a39Sopenharmony_ci ivec -= 8; 120e1051a39Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 121e1051a39Sopenharmony_ci n2l(in, tin0); 122e1051a39Sopenharmony_ci n2l(in, tin1); 123e1051a39Sopenharmony_ci tin0 ^= tout0; 124e1051a39Sopenharmony_ci tin1 ^= tout1; 125e1051a39Sopenharmony_ci tin[0] = tin0; 126e1051a39Sopenharmony_ci tin[1] = tin1; 127e1051a39Sopenharmony_ci BF_encrypt(tin, schedule); 128e1051a39Sopenharmony_ci tout0 = tin[0]; 129e1051a39Sopenharmony_ci tout1 = tin[1]; 130e1051a39Sopenharmony_ci l2n(tout0, out); 131e1051a39Sopenharmony_ci l2n(tout1, out); 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci if (l != -8) { 134e1051a39Sopenharmony_ci n2ln(in, tin0, tin1, l + 8); 135e1051a39Sopenharmony_ci tin0 ^= tout0; 136e1051a39Sopenharmony_ci tin1 ^= tout1; 137e1051a39Sopenharmony_ci tin[0] = tin0; 138e1051a39Sopenharmony_ci tin[1] = tin1; 139e1051a39Sopenharmony_ci BF_encrypt(tin, schedule); 140e1051a39Sopenharmony_ci tout0 = tin[0]; 141e1051a39Sopenharmony_ci tout1 = tin[1]; 142e1051a39Sopenharmony_ci l2n(tout0, out); 143e1051a39Sopenharmony_ci l2n(tout1, out); 144e1051a39Sopenharmony_ci } 145e1051a39Sopenharmony_ci l2n(tout0, ivec); 146e1051a39Sopenharmony_ci l2n(tout1, ivec); 147e1051a39Sopenharmony_ci } else { 148e1051a39Sopenharmony_ci n2l(ivec, xor0); 149e1051a39Sopenharmony_ci n2l(ivec, xor1); 150e1051a39Sopenharmony_ci ivec -= 8; 151e1051a39Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 152e1051a39Sopenharmony_ci n2l(in, tin0); 153e1051a39Sopenharmony_ci n2l(in, tin1); 154e1051a39Sopenharmony_ci tin[0] = tin0; 155e1051a39Sopenharmony_ci tin[1] = tin1; 156e1051a39Sopenharmony_ci BF_decrypt(tin, schedule); 157e1051a39Sopenharmony_ci tout0 = tin[0] ^ xor0; 158e1051a39Sopenharmony_ci tout1 = tin[1] ^ xor1; 159e1051a39Sopenharmony_ci l2n(tout0, out); 160e1051a39Sopenharmony_ci l2n(tout1, out); 161e1051a39Sopenharmony_ci xor0 = tin0; 162e1051a39Sopenharmony_ci xor1 = tin1; 163e1051a39Sopenharmony_ci } 164e1051a39Sopenharmony_ci if (l != -8) { 165e1051a39Sopenharmony_ci n2l(in, tin0); 166e1051a39Sopenharmony_ci n2l(in, tin1); 167e1051a39Sopenharmony_ci tin[0] = tin0; 168e1051a39Sopenharmony_ci tin[1] = tin1; 169e1051a39Sopenharmony_ci BF_decrypt(tin, schedule); 170e1051a39Sopenharmony_ci tout0 = tin[0] ^ xor0; 171e1051a39Sopenharmony_ci tout1 = tin[1] ^ xor1; 172e1051a39Sopenharmony_ci l2nn(tout0, tout1, out, l + 8); 173e1051a39Sopenharmony_ci xor0 = tin0; 174e1051a39Sopenharmony_ci xor1 = tin1; 175e1051a39Sopenharmony_ci } 176e1051a39Sopenharmony_ci l2n(xor0, ivec); 177e1051a39Sopenharmony_ci l2n(xor1, ivec); 178e1051a39Sopenharmony_ci } 179e1051a39Sopenharmony_ci tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 180e1051a39Sopenharmony_ci tin[0] = tin[1] = 0; 181e1051a39Sopenharmony_ci} 182