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 * RC2 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/rc2.h> 17e1051a39Sopenharmony_ci#include "rc2_local.h" 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_civoid RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, 20e1051a39Sopenharmony_ci RC2_KEY *ks, unsigned char *iv, int encrypt) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci register unsigned long tin0, tin1; 23e1051a39Sopenharmony_ci register unsigned long tout0, tout1, xor0, xor1; 24e1051a39Sopenharmony_ci register long l = length; 25e1051a39Sopenharmony_ci unsigned long tin[2]; 26e1051a39Sopenharmony_ci 27e1051a39Sopenharmony_ci if (encrypt) { 28e1051a39Sopenharmony_ci c2l(iv, tout0); 29e1051a39Sopenharmony_ci c2l(iv, tout1); 30e1051a39Sopenharmony_ci iv -= 8; 31e1051a39Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 32e1051a39Sopenharmony_ci c2l(in, tin0); 33e1051a39Sopenharmony_ci c2l(in, tin1); 34e1051a39Sopenharmony_ci tin0 ^= tout0; 35e1051a39Sopenharmony_ci tin1 ^= tout1; 36e1051a39Sopenharmony_ci tin[0] = tin0; 37e1051a39Sopenharmony_ci tin[1] = tin1; 38e1051a39Sopenharmony_ci RC2_encrypt(tin, ks); 39e1051a39Sopenharmony_ci tout0 = tin[0]; 40e1051a39Sopenharmony_ci l2c(tout0, out); 41e1051a39Sopenharmony_ci tout1 = tin[1]; 42e1051a39Sopenharmony_ci l2c(tout1, out); 43e1051a39Sopenharmony_ci } 44e1051a39Sopenharmony_ci if (l != -8) { 45e1051a39Sopenharmony_ci c2ln(in, tin0, tin1, l + 8); 46e1051a39Sopenharmony_ci tin0 ^= tout0; 47e1051a39Sopenharmony_ci tin1 ^= tout1; 48e1051a39Sopenharmony_ci tin[0] = tin0; 49e1051a39Sopenharmony_ci tin[1] = tin1; 50e1051a39Sopenharmony_ci RC2_encrypt(tin, ks); 51e1051a39Sopenharmony_ci tout0 = tin[0]; 52e1051a39Sopenharmony_ci l2c(tout0, out); 53e1051a39Sopenharmony_ci tout1 = tin[1]; 54e1051a39Sopenharmony_ci l2c(tout1, out); 55e1051a39Sopenharmony_ci } 56e1051a39Sopenharmony_ci l2c(tout0, iv); 57e1051a39Sopenharmony_ci l2c(tout1, iv); 58e1051a39Sopenharmony_ci } else { 59e1051a39Sopenharmony_ci c2l(iv, xor0); 60e1051a39Sopenharmony_ci c2l(iv, xor1); 61e1051a39Sopenharmony_ci iv -= 8; 62e1051a39Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 63e1051a39Sopenharmony_ci c2l(in, tin0); 64e1051a39Sopenharmony_ci tin[0] = tin0; 65e1051a39Sopenharmony_ci c2l(in, tin1); 66e1051a39Sopenharmony_ci tin[1] = tin1; 67e1051a39Sopenharmony_ci RC2_decrypt(tin, ks); 68e1051a39Sopenharmony_ci tout0 = tin[0] ^ xor0; 69e1051a39Sopenharmony_ci tout1 = tin[1] ^ xor1; 70e1051a39Sopenharmony_ci l2c(tout0, out); 71e1051a39Sopenharmony_ci l2c(tout1, out); 72e1051a39Sopenharmony_ci xor0 = tin0; 73e1051a39Sopenharmony_ci xor1 = tin1; 74e1051a39Sopenharmony_ci } 75e1051a39Sopenharmony_ci if (l != -8) { 76e1051a39Sopenharmony_ci c2l(in, tin0); 77e1051a39Sopenharmony_ci tin[0] = tin0; 78e1051a39Sopenharmony_ci c2l(in, tin1); 79e1051a39Sopenharmony_ci tin[1] = tin1; 80e1051a39Sopenharmony_ci RC2_decrypt(tin, ks); 81e1051a39Sopenharmony_ci tout0 = tin[0] ^ xor0; 82e1051a39Sopenharmony_ci tout1 = tin[1] ^ xor1; 83e1051a39Sopenharmony_ci l2cn(tout0, tout1, out, l + 8); 84e1051a39Sopenharmony_ci xor0 = tin0; 85e1051a39Sopenharmony_ci xor1 = tin1; 86e1051a39Sopenharmony_ci } 87e1051a39Sopenharmony_ci l2c(xor0, iv); 88e1051a39Sopenharmony_ci l2c(xor1, iv); 89e1051a39Sopenharmony_ci } 90e1051a39Sopenharmony_ci tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 91e1051a39Sopenharmony_ci tin[0] = tin[1] = 0; 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_civoid RC2_encrypt(unsigned long *d, RC2_KEY *key) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci int i, n; 97e1051a39Sopenharmony_ci register RC2_INT *p0, *p1; 98e1051a39Sopenharmony_ci register RC2_INT x0, x1, x2, x3, t; 99e1051a39Sopenharmony_ci unsigned long l; 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci l = d[0]; 102e1051a39Sopenharmony_ci x0 = (RC2_INT) l & 0xffff; 103e1051a39Sopenharmony_ci x1 = (RC2_INT) (l >> 16L); 104e1051a39Sopenharmony_ci l = d[1]; 105e1051a39Sopenharmony_ci x2 = (RC2_INT) l & 0xffff; 106e1051a39Sopenharmony_ci x3 = (RC2_INT) (l >> 16L); 107e1051a39Sopenharmony_ci 108e1051a39Sopenharmony_ci n = 3; 109e1051a39Sopenharmony_ci i = 5; 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci p0 = p1 = &(key->data[0]); 112e1051a39Sopenharmony_ci for (;;) { 113e1051a39Sopenharmony_ci t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; 114e1051a39Sopenharmony_ci x0 = (t << 1) | (t >> 15); 115e1051a39Sopenharmony_ci t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; 116e1051a39Sopenharmony_ci x1 = (t << 2) | (t >> 14); 117e1051a39Sopenharmony_ci t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; 118e1051a39Sopenharmony_ci x2 = (t << 3) | (t >> 13); 119e1051a39Sopenharmony_ci t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; 120e1051a39Sopenharmony_ci x3 = (t << 5) | (t >> 11); 121e1051a39Sopenharmony_ci 122e1051a39Sopenharmony_ci if (--i == 0) { 123e1051a39Sopenharmony_ci if (--n == 0) 124e1051a39Sopenharmony_ci break; 125e1051a39Sopenharmony_ci i = (n == 2) ? 6 : 5; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci x0 += p1[x3 & 0x3f]; 128e1051a39Sopenharmony_ci x1 += p1[x0 & 0x3f]; 129e1051a39Sopenharmony_ci x2 += p1[x1 & 0x3f]; 130e1051a39Sopenharmony_ci x3 += p1[x2 & 0x3f]; 131e1051a39Sopenharmony_ci } 132e1051a39Sopenharmony_ci } 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci d[0] = 135e1051a39Sopenharmony_ci (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); 136e1051a39Sopenharmony_ci d[1] = 137e1051a39Sopenharmony_ci (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); 138e1051a39Sopenharmony_ci} 139e1051a39Sopenharmony_ci 140e1051a39Sopenharmony_civoid RC2_decrypt(unsigned long *d, RC2_KEY *key) 141e1051a39Sopenharmony_ci{ 142e1051a39Sopenharmony_ci int i, n; 143e1051a39Sopenharmony_ci register RC2_INT *p0, *p1; 144e1051a39Sopenharmony_ci register RC2_INT x0, x1, x2, x3, t; 145e1051a39Sopenharmony_ci unsigned long l; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci l = d[0]; 148e1051a39Sopenharmony_ci x0 = (RC2_INT) l & 0xffff; 149e1051a39Sopenharmony_ci x1 = (RC2_INT) (l >> 16L); 150e1051a39Sopenharmony_ci l = d[1]; 151e1051a39Sopenharmony_ci x2 = (RC2_INT) l & 0xffff; 152e1051a39Sopenharmony_ci x3 = (RC2_INT) (l >> 16L); 153e1051a39Sopenharmony_ci 154e1051a39Sopenharmony_ci n = 3; 155e1051a39Sopenharmony_ci i = 5; 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci p0 = &(key->data[63]); 158e1051a39Sopenharmony_ci p1 = &(key->data[0]); 159e1051a39Sopenharmony_ci for (;;) { 160e1051a39Sopenharmony_ci t = ((x3 << 11) | (x3 >> 5)) & 0xffff; 161e1051a39Sopenharmony_ci x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; 162e1051a39Sopenharmony_ci t = ((x2 << 13) | (x2 >> 3)) & 0xffff; 163e1051a39Sopenharmony_ci x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; 164e1051a39Sopenharmony_ci t = ((x1 << 14) | (x1 >> 2)) & 0xffff; 165e1051a39Sopenharmony_ci x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; 166e1051a39Sopenharmony_ci t = ((x0 << 15) | (x0 >> 1)) & 0xffff; 167e1051a39Sopenharmony_ci x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci if (--i == 0) { 170e1051a39Sopenharmony_ci if (--n == 0) 171e1051a39Sopenharmony_ci break; 172e1051a39Sopenharmony_ci i = (n == 2) ? 6 : 5; 173e1051a39Sopenharmony_ci 174e1051a39Sopenharmony_ci x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; 175e1051a39Sopenharmony_ci x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; 176e1051a39Sopenharmony_ci x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; 177e1051a39Sopenharmony_ci x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; 178e1051a39Sopenharmony_ci } 179e1051a39Sopenharmony_ci } 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ci d[0] = 182e1051a39Sopenharmony_ci (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); 183e1051a39Sopenharmony_ci d[1] = 184e1051a39Sopenharmony_ci (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); 185e1051a39Sopenharmony_ci} 186