|  | /* | 
|  | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. | 
|  | * | 
|  | * Licensed under the Apache License 2.0 (the "License").  You may not use | 
|  | * this file except in compliance with the License.  You can obtain a copy | 
|  | * in the file LICENSE in the source distribution or at | 
|  | * https://www.openssl.org/source/license.html | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * RC5 low level APIs are deprecated for public use, but still ok for internal | 
|  | * use. | 
|  | */ | 
|  | #include "internal/deprecated.h" | 
|  |  | 
|  | #include <openssl/rc5.h> | 
|  | #include "rc5_local.h" | 
|  |  | 
|  | int RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, | 
|  | int rounds) | 
|  | { | 
|  | RC5_32_INT L[64], l, ll, A, B, *S, k; | 
|  | int i, j, m, c, t, ii, jj; | 
|  |  | 
|  | if (len > 255) | 
|  | return 0; | 
|  |  | 
|  | if ((rounds != RC5_16_ROUNDS) && | 
|  | (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) | 
|  | rounds = RC5_16_ROUNDS; | 
|  |  | 
|  | key->rounds = rounds; | 
|  | S = &(key->data[0]); | 
|  | j = 0; | 
|  | for (i = 0; i <= (len - 8); i += 8) { | 
|  | c2l(data, l); | 
|  | L[j++] = l; | 
|  | c2l(data, l); | 
|  | L[j++] = l; | 
|  | } | 
|  | ii = len - i; | 
|  | if (ii) { | 
|  | k = len & 0x07; | 
|  | c2ln(data, l, ll, k); | 
|  | L[j + 0] = l; | 
|  | L[j + 1] = ll; | 
|  | } | 
|  |  | 
|  | c = (len + 3) / 4; | 
|  | t = (rounds + 1) * 2; | 
|  | S[0] = RC5_32_P; | 
|  | for (i = 1; i < t; i++) | 
|  | S[i] = (S[i - 1] + RC5_32_Q) & RC5_32_MASK; | 
|  |  | 
|  | j = (t > c) ? t : c; | 
|  | j *= 3; | 
|  | ii = jj = 0; | 
|  | A = B = 0; | 
|  | for (i = 0; i < j; i++) { | 
|  | k = (S[ii] + A + B) & RC5_32_MASK; | 
|  | A = S[ii] = ROTATE_l32(k, 3); | 
|  | m = (int)(A + B); | 
|  | k = (L[jj] + A + B) & RC5_32_MASK; | 
|  | B = L[jj] = ROTATE_l32(k, m); | 
|  | if (++ii >= t) | 
|  | ii = 0; | 
|  | if (++jj >= c) | 
|  | jj = 0; | 
|  | } | 
|  |  | 
|  | return 1; | 
|  | } |