1/* 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (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/* 11 * RC5 low level APIs are deprecated for public use, but still ok for internal 12 * use. 13 */ 14#include "internal/deprecated.h" 15 16#include <stdio.h> 17#include <openssl/rc5.h> 18#include "rc5_local.h" 19 20void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, 21 long length, RC5_32_KEY *ks, unsigned char *iv, 22 int encrypt) 23{ 24 register unsigned long tin0, tin1; 25 register unsigned long tout0, tout1, xor0, xor1; 26 register long l = length; 27 unsigned long tin[2]; 28 29 if (encrypt) { 30 c2l(iv, tout0); 31 c2l(iv, tout1); 32 iv -= 8; 33 for (l -= 8; l >= 0; l -= 8) { 34 c2l(in, tin0); 35 c2l(in, tin1); 36 tin0 ^= tout0; 37 tin1 ^= tout1; 38 tin[0] = tin0; 39 tin[1] = tin1; 40 RC5_32_encrypt(tin, ks); 41 tout0 = tin[0]; 42 l2c(tout0, out); 43 tout1 = tin[1]; 44 l2c(tout1, out); 45 } 46 if (l != -8) { 47 c2ln(in, tin0, tin1, l + 8); 48 tin0 ^= tout0; 49 tin1 ^= tout1; 50 tin[0] = tin0; 51 tin[1] = tin1; 52 RC5_32_encrypt(tin, ks); 53 tout0 = tin[0]; 54 l2c(tout0, out); 55 tout1 = tin[1]; 56 l2c(tout1, out); 57 } 58 l2c(tout0, iv); 59 l2c(tout1, iv); 60 } else { 61 c2l(iv, xor0); 62 c2l(iv, xor1); 63 iv -= 8; 64 for (l -= 8; l >= 0; l -= 8) { 65 c2l(in, tin0); 66 tin[0] = tin0; 67 c2l(in, tin1); 68 tin[1] = tin1; 69 RC5_32_decrypt(tin, ks); 70 tout0 = tin[0] ^ xor0; 71 tout1 = tin[1] ^ xor1; 72 l2c(tout0, out); 73 l2c(tout1, out); 74 xor0 = tin0; 75 xor1 = tin1; 76 } 77 if (l != -8) { 78 c2l(in, tin0); 79 tin[0] = tin0; 80 c2l(in, tin1); 81 tin[1] = tin1; 82 RC5_32_decrypt(tin, ks); 83 tout0 = tin[0] ^ xor0; 84 tout1 = tin[1] ^ xor1; 85 l2cn(tout0, tout1, out, l + 8); 86 xor0 = tin0; 87 xor1 = tin1; 88 } 89 l2c(xor0, iv); 90 l2c(xor1, iv); 91 } 92 tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 93 tin[0] = tin[1] = 0; 94} 95 96void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key) 97{ 98 RC5_32_INT a, b, *s; 99 100 s = key->data; 101 102 a = d[0] + s[0]; 103 b = d[1] + s[1]; 104 E_RC5_32(a, b, s, 2); 105 E_RC5_32(a, b, s, 4); 106 E_RC5_32(a, b, s, 6); 107 E_RC5_32(a, b, s, 8); 108 E_RC5_32(a, b, s, 10); 109 E_RC5_32(a, b, s, 12); 110 E_RC5_32(a, b, s, 14); 111 E_RC5_32(a, b, s, 16); 112 if (key->rounds == 12) { 113 E_RC5_32(a, b, s, 18); 114 E_RC5_32(a, b, s, 20); 115 E_RC5_32(a, b, s, 22); 116 E_RC5_32(a, b, s, 24); 117 } else if (key->rounds == 16) { 118 /* Do a full expansion to avoid a jump */ 119 E_RC5_32(a, b, s, 18); 120 E_RC5_32(a, b, s, 20); 121 E_RC5_32(a, b, s, 22); 122 E_RC5_32(a, b, s, 24); 123 E_RC5_32(a, b, s, 26); 124 E_RC5_32(a, b, s, 28); 125 E_RC5_32(a, b, s, 30); 126 E_RC5_32(a, b, s, 32); 127 } 128 d[0] = a; 129 d[1] = b; 130} 131 132void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key) 133{ 134 RC5_32_INT a, b, *s; 135 136 s = key->data; 137 138 a = d[0]; 139 b = d[1]; 140 if (key->rounds == 16) { 141 D_RC5_32(a, b, s, 32); 142 D_RC5_32(a, b, s, 30); 143 D_RC5_32(a, b, s, 28); 144 D_RC5_32(a, b, s, 26); 145 /* Do a full expansion to avoid a jump */ 146 D_RC5_32(a, b, s, 24); 147 D_RC5_32(a, b, s, 22); 148 D_RC5_32(a, b, s, 20); 149 D_RC5_32(a, b, s, 18); 150 } else if (key->rounds == 12) { 151 D_RC5_32(a, b, s, 24); 152 D_RC5_32(a, b, s, 22); 153 D_RC5_32(a, b, s, 20); 154 D_RC5_32(a, b, s, 18); 155 } 156 D_RC5_32(a, b, s, 16); 157 D_RC5_32(a, b, s, 14); 158 D_RC5_32(a, b, s, 12); 159 D_RC5_32(a, b, s, 10); 160 D_RC5_32(a, b, s, 8); 161 D_RC5_32(a, b, s, 6); 162 D_RC5_32(a, b, s, 4); 163 D_RC5_32(a, b, s, 2); 164 d[0] = a - s[0]; 165 d[1] = b - s[1]; 166} 167