| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /* ===================================================================
- *
- * Copyright (c) 2019, Helder Eijs <helderijs@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- * ===================================================================
- */
- #include "common.h"
- #include "endianess.h"
- #include "block_base.h"
- #include "blowfish_init.c"
- #ifdef EKS
- #define NON_STANDARD_START_OPERATION
- #define MODULE_NAME EKSBlowfish
- FAKE_INIT(raw_eksblowfish)
- #else
- #define MODULE_NAME Blowfish
- FAKE_INIT(raw_blowfish)
- #endif
- #define BLOCK_SIZE 8
- #define KEY_SIZE 0
- struct block_state {
- uint32_t S[4][256];
- uint32_t P[18];
- };
- static inline void swap(uint32_t *L, uint32_t *R)
- {
- uint32_t tmp;
- tmp = *L;
- *L = *R;
- *R = tmp;
- }
- static inline uint32_t F(const struct block_state *ctx, uint32_t x)
- {
- uint8_t a, b, c, d;
- uint32_t res;
- a = (x >> 24) & 0xFF;
- b = (x >> 16) & 0xFF;
- c = (x >> 8) & 0xFF;
- d = (x >> 0) & 0xFF;
- res = ctx->S[0][a] + ctx->S[1][b];
- res ^= ctx->S[2][c];
- res += ctx->S[3][d];
- return res;
- }
- static void bf_encrypt(const struct block_state *state, uint32_t *Lx, uint32_t *Rx)
- {
- unsigned i;
- uint32_t L, R;
- L = *Lx;
- R = *Rx;
- for (i=0; i<16; i++) {
- L ^= state->P[i];
- R ^= F(state, L);
- swap(&L, &R);
- }
- swap(&L, &R);
- R ^= state->P[16];
- L ^= state->P[17];
- *Lx = L;
- *Rx = R;
- }
- static void bf_decrypt(const struct block_state *state, uint32_t *Lx, uint32_t *Rx)
- {
- unsigned i;
- uint32_t L, R;
- L = *Lx;
- R = *Rx;
- L ^= state->P[17];
- R ^= state->P[16];
- swap(&L, &R);
- for (i=0; i<16; i++) {
- swap(&L, &R);
- R ^= F(state, L);
- L ^= state->P[15-i];
- }
- *Lx = L;
- *Rx = R;
- }
- static inline void xorP(uint32_t P[18], const uint8_t *key, size_t keylength)
- {
- uint8_t P_buf[4*18];
- size_t P_idx;
- unsigned i;
- P_idx = 0;
- while (P_idx < sizeof(P_buf)) {
- size_t tc;
- tc = MIN(keylength, sizeof(P_buf) - P_idx);
- memcpy(P_buf + P_idx, key, tc);
- P_idx += tc;
- }
- P_idx = 0;
- for (i=0; i<18; i++) {
- P[i] ^= LOAD_U32_BIG(P_buf + P_idx);
- P_idx += 4;
- }
- }
- static inline void encryptState(struct block_state *state, const uint8_t *key, size_t keylength)
- {
- unsigned i, j;
- uint32_t L, R;
- xorP(state->P, key, keylength);
- L = R = 0;
- for (i=0; i<18; i+=2) {
- bf_encrypt(state, &L, &R);
- state->P[i] = L;
- state->P[i+1] = R;
- }
- for (j=0; j<4; j++) {
- for (i=0; i<256; i+=2) {
- bf_encrypt(state, &L, &R);
- state->S[j][i] = L;
- state->S[j][i+1] = R;
- }
- }
- }
- #ifndef EKS
- static int block_init(struct block_state *state, const uint8_t *key, size_t keylength)
- {
- /* Allowed key length: 32 to 448 bits */
- if (keylength < 4 || keylength > 56) {
- return ERR_KEY_SIZE;
- }
- memcpy(state->S, S_init, sizeof S_init);
- memcpy(state->P, P_init, sizeof P_init);
- encryptState(state, key, keylength);
- return 0;
- }
- #else
- static inline uint32_t read_u32_circ(const uint8_t *base, size_t len, size_t *idx)
- {
- uint8_t buf[4];
- unsigned i;
- for (i=0; i<4; i++) {
- buf[i] = base[*idx];
- (*idx)++;
- if (len == *idx)
- *idx = 0;
- }
- return LOAD_U32_BIG(buf);
- }
- static int encryptStateWithSalt(struct block_state *state, const uint8_t *key, size_t keylength, const uint8_t *salt, size_t saltlength)
- {
- uint32_t L, R;
- unsigned i, j;
- size_t idx;
- xorP(state->P, key, keylength);
- L = R = 0;
- idx = 0;
- for (i=0; i<18; i+=2) {
- L ^= read_u32_circ(salt, saltlength, &idx);
- R ^= read_u32_circ(salt, saltlength, &idx);
- bf_encrypt(state, &L, &R);
- state->P[i] = L;
- state->P[i+1] = R;
- }
- for (j=0; j<4; j++) {
- for (i=0; i<256; i+=2) {
- L ^= read_u32_circ(salt, saltlength, &idx);
- R ^= read_u32_circ(salt, saltlength, &idx);
- bf_encrypt(state, &L, &R);
- state->S[j][i] = L;
- state->S[j][i+1] = R;
- }
- }
- return 0;
- }
- static int block_init(struct block_state *state, const uint8_t *key, size_t keylength, const uint8_t *salt, size_t saltlength, unsigned cost, unsigned invert)
- {
- unsigned i;
- unsigned iterations;
- if (keylength > 72) {
- return ERR_KEY_SIZE;
- }
- /* InitState */
- memcpy(state->S, S_init, sizeof S_init);
- memcpy(state->P, P_init, sizeof P_init);
- encryptStateWithSalt(state, key, keylength, salt, saltlength);
- iterations = 1U << cost;
- if (!invert) {
- for (i=0; i<iterations; i++) {
- encryptState(state, salt, saltlength);
- encryptState(state, key, keylength);
- }
- } else {
- for (i=0; i<iterations; i++) {
- encryptState(state, key, keylength);
- encryptState(state, salt, saltlength);
- }
- }
- return 0;
- }
- #endif
- static void block_finalize(struct block_state* state)
- {
- }
- static inline void block_encrypt(struct block_state *state, const uint8_t *in, uint8_t *out)
- {
- uint32_t L, R;
- L = LOAD_U32_BIG(in);
- R = LOAD_U32_BIG(in + 4);
- bf_encrypt(state, &L, &R);
- STORE_U32_BIG(out, L);
- STORE_U32_BIG(out + 4, R);
- }
- static inline void block_decrypt(struct block_state *state, const uint8_t *in, uint8_t *out)
- {
- uint32_t L, R;
- L = LOAD_U32_BIG(in);
- R = LOAD_U32_BIG(in + 4);
- bf_decrypt(state, &L, &R);
- STORE_U32_BIG(out, L);
- STORE_U32_BIG(out + 4, R);
- }
- #include "block_common.c"
- #ifdef EKS
- EXPORT_SYM int CIPHER_START_OPERATION(const uint8_t key[], size_t key_len, const uint8_t salt[], size_t salt_len, unsigned cost, unsigned invert, CIPHER_STATE_TYPE **pResult)
- {
- BlockBase *block_base;
- if ((key == NULL) || (salt == NULL) || (pResult == NULL))
- return ERR_NULL;
- *pResult = calloc(1, sizeof(CIPHER_STATE_TYPE));
- if (NULL == *pResult)
- return ERR_MEMORY;
- block_base = &((*pResult)->base_state);
- block_base->encrypt = &CIPHER_ENCRYPT;
- block_base->decrypt = &CIPHER_DECRYPT;
- block_base->destructor = &CIPHER_STOP_OPERATION;
- block_base->block_len = BLOCK_SIZE;
- return block_init(&(*pResult)->algo_state, (unsigned char*)key, key_len, salt, salt_len, cost, invert);
- }
- #endif
|