1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/rc5.h> 11 #include "rc5_local.h" 12 13 void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, 14 int rounds) 15 { 16 RC5_32_INT L[64], l, ll, A, B, *S, k; 17 int i, j, m, c, t, ii, jj; 18 19 if ((rounds != RC5_16_ROUNDS) && 20 (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) 21 rounds = RC5_16_ROUNDS; 22 23 key->rounds = rounds; 24 S = &(key->data[0]); 25 j = 0; 26 for (i = 0; i <= (len - 8); i += 8) { 27 c2l(data, l); 28 L[j++] = l; 29 c2l(data, l); 30 L[j++] = l; 31 } 32 ii = len - i; 33 if (ii) { 34 k = len & 0x07; 35 c2ln(data, l, ll, k); 36 L[j + 0] = l; 37 L[j + 1] = ll; 38 } 39 40 c = (len + 3) / 4; 41 t = (rounds + 1) * 2; 42 S[0] = RC5_32_P; 43 for (i = 1; i < t; i++) 44 S[i] = (S[i - 1] + RC5_32_Q) & RC5_32_MASK; 45 46 j = (t > c) ? t : c; 47 j *= 3; 48 ii = jj = 0; 49 A = B = 0; 50 for (i = 0; i < j; i++) { 51 k = (S[ii] + A + B) & RC5_32_MASK; 52 A = S[ii] = ROTATE_l32(k, 3); 53 m = (int)(A + B); 54 k = (L[jj] + A + B) & RC5_32_MASK; 55 B = L[jj] = ROTATE_l32(k, m); 56 if (++ii >= t) 57 ii = 0; 58 if (++jj >= c) 59 jj = 0; 60 } 61 } 62