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 * RC5 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/rc5.h> 17e1051a39Sopenharmony_ci#include "rc5_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ciint RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, 20e1051a39Sopenharmony_ci int rounds) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci RC5_32_INT L[64], l, ll, A, B, *S, k; 23e1051a39Sopenharmony_ci int i, j, m, c, t, ii, jj; 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci if (len > 255) 26e1051a39Sopenharmony_ci return 0; 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ci if ((rounds != RC5_16_ROUNDS) && 29e1051a39Sopenharmony_ci (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) 30e1051a39Sopenharmony_ci rounds = RC5_16_ROUNDS; 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci key->rounds = rounds; 33e1051a39Sopenharmony_ci S = &(key->data[0]); 34e1051a39Sopenharmony_ci j = 0; 35e1051a39Sopenharmony_ci for (i = 0; i <= (len - 8); i += 8) { 36e1051a39Sopenharmony_ci c2l(data, l); 37e1051a39Sopenharmony_ci L[j++] = l; 38e1051a39Sopenharmony_ci c2l(data, l); 39e1051a39Sopenharmony_ci L[j++] = l; 40e1051a39Sopenharmony_ci } 41e1051a39Sopenharmony_ci ii = len - i; 42e1051a39Sopenharmony_ci if (ii) { 43e1051a39Sopenharmony_ci k = len & 0x07; 44e1051a39Sopenharmony_ci c2ln(data, l, ll, k); 45e1051a39Sopenharmony_ci L[j + 0] = l; 46e1051a39Sopenharmony_ci L[j + 1] = ll; 47e1051a39Sopenharmony_ci } 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci c = (len + 3) / 4; 50e1051a39Sopenharmony_ci t = (rounds + 1) * 2; 51e1051a39Sopenharmony_ci S[0] = RC5_32_P; 52e1051a39Sopenharmony_ci for (i = 1; i < t; i++) 53e1051a39Sopenharmony_ci S[i] = (S[i - 1] + RC5_32_Q) & RC5_32_MASK; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci j = (t > c) ? t : c; 56e1051a39Sopenharmony_ci j *= 3; 57e1051a39Sopenharmony_ci ii = jj = 0; 58e1051a39Sopenharmony_ci A = B = 0; 59e1051a39Sopenharmony_ci for (i = 0; i < j; i++) { 60e1051a39Sopenharmony_ci k = (S[ii] + A + B) & RC5_32_MASK; 61e1051a39Sopenharmony_ci A = S[ii] = ROTATE_l32(k, 3); 62e1051a39Sopenharmony_ci m = (int)(A + B); 63e1051a39Sopenharmony_ci k = (L[jj] + A + B) & RC5_32_MASK; 64e1051a39Sopenharmony_ci B = L[jj] = ROTATE_l32(k, m); 65e1051a39Sopenharmony_ci if (++ii >= t) 66e1051a39Sopenharmony_ci ii = 0; 67e1051a39Sopenharmony_ci if (++jj >= c) 68e1051a39Sopenharmony_ci jj = 0; 69e1051a39Sopenharmony_ci } 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_ci return 1; 72e1051a39Sopenharmony_ci} 73