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