11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 51cb0ef41Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at 71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci/* 111cb0ef41Sopenharmony_ci * RC5 low level APIs are deprecated for public use, but still ok for internal 121cb0ef41Sopenharmony_ci * use. 131cb0ef41Sopenharmony_ci */ 141cb0ef41Sopenharmony_ci#include "internal/deprecated.h" 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_ci#include <stdio.h> 171cb0ef41Sopenharmony_ci#include <openssl/rc5.h> 181cb0ef41Sopenharmony_ci#include "rc5_local.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_civoid RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, 211cb0ef41Sopenharmony_ci long length, RC5_32_KEY *ks, unsigned char *iv, 221cb0ef41Sopenharmony_ci int encrypt) 231cb0ef41Sopenharmony_ci{ 241cb0ef41Sopenharmony_ci register unsigned long tin0, tin1; 251cb0ef41Sopenharmony_ci register unsigned long tout0, tout1, xor0, xor1; 261cb0ef41Sopenharmony_ci register long l = length; 271cb0ef41Sopenharmony_ci unsigned long tin[2]; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci if (encrypt) { 301cb0ef41Sopenharmony_ci c2l(iv, tout0); 311cb0ef41Sopenharmony_ci c2l(iv, tout1); 321cb0ef41Sopenharmony_ci iv -= 8; 331cb0ef41Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 341cb0ef41Sopenharmony_ci c2l(in, tin0); 351cb0ef41Sopenharmony_ci c2l(in, tin1); 361cb0ef41Sopenharmony_ci tin0 ^= tout0; 371cb0ef41Sopenharmony_ci tin1 ^= tout1; 381cb0ef41Sopenharmony_ci tin[0] = tin0; 391cb0ef41Sopenharmony_ci tin[1] = tin1; 401cb0ef41Sopenharmony_ci RC5_32_encrypt(tin, ks); 411cb0ef41Sopenharmony_ci tout0 = tin[0]; 421cb0ef41Sopenharmony_ci l2c(tout0, out); 431cb0ef41Sopenharmony_ci tout1 = tin[1]; 441cb0ef41Sopenharmony_ci l2c(tout1, out); 451cb0ef41Sopenharmony_ci } 461cb0ef41Sopenharmony_ci if (l != -8) { 471cb0ef41Sopenharmony_ci c2ln(in, tin0, tin1, l + 8); 481cb0ef41Sopenharmony_ci tin0 ^= tout0; 491cb0ef41Sopenharmony_ci tin1 ^= tout1; 501cb0ef41Sopenharmony_ci tin[0] = tin0; 511cb0ef41Sopenharmony_ci tin[1] = tin1; 521cb0ef41Sopenharmony_ci RC5_32_encrypt(tin, ks); 531cb0ef41Sopenharmony_ci tout0 = tin[0]; 541cb0ef41Sopenharmony_ci l2c(tout0, out); 551cb0ef41Sopenharmony_ci tout1 = tin[1]; 561cb0ef41Sopenharmony_ci l2c(tout1, out); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci l2c(tout0, iv); 591cb0ef41Sopenharmony_ci l2c(tout1, iv); 601cb0ef41Sopenharmony_ci } else { 611cb0ef41Sopenharmony_ci c2l(iv, xor0); 621cb0ef41Sopenharmony_ci c2l(iv, xor1); 631cb0ef41Sopenharmony_ci iv -= 8; 641cb0ef41Sopenharmony_ci for (l -= 8; l >= 0; l -= 8) { 651cb0ef41Sopenharmony_ci c2l(in, tin0); 661cb0ef41Sopenharmony_ci tin[0] = tin0; 671cb0ef41Sopenharmony_ci c2l(in, tin1); 681cb0ef41Sopenharmony_ci tin[1] = tin1; 691cb0ef41Sopenharmony_ci RC5_32_decrypt(tin, ks); 701cb0ef41Sopenharmony_ci tout0 = tin[0] ^ xor0; 711cb0ef41Sopenharmony_ci tout1 = tin[1] ^ xor1; 721cb0ef41Sopenharmony_ci l2c(tout0, out); 731cb0ef41Sopenharmony_ci l2c(tout1, out); 741cb0ef41Sopenharmony_ci xor0 = tin0; 751cb0ef41Sopenharmony_ci xor1 = tin1; 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci if (l != -8) { 781cb0ef41Sopenharmony_ci c2l(in, tin0); 791cb0ef41Sopenharmony_ci tin[0] = tin0; 801cb0ef41Sopenharmony_ci c2l(in, tin1); 811cb0ef41Sopenharmony_ci tin[1] = tin1; 821cb0ef41Sopenharmony_ci RC5_32_decrypt(tin, ks); 831cb0ef41Sopenharmony_ci tout0 = tin[0] ^ xor0; 841cb0ef41Sopenharmony_ci tout1 = tin[1] ^ xor1; 851cb0ef41Sopenharmony_ci l2cn(tout0, tout1, out, l + 8); 861cb0ef41Sopenharmony_ci xor0 = tin0; 871cb0ef41Sopenharmony_ci xor1 = tin1; 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci l2c(xor0, iv); 901cb0ef41Sopenharmony_ci l2c(xor1, iv); 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; 931cb0ef41Sopenharmony_ci tin[0] = tin[1] = 0; 941cb0ef41Sopenharmony_ci} 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_civoid RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key) 971cb0ef41Sopenharmony_ci{ 981cb0ef41Sopenharmony_ci RC5_32_INT a, b, *s; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci s = key->data; 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci a = d[0] + s[0]; 1031cb0ef41Sopenharmony_ci b = d[1] + s[1]; 1041cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 2); 1051cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 4); 1061cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 6); 1071cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 8); 1081cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 10); 1091cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 12); 1101cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 14); 1111cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 16); 1121cb0ef41Sopenharmony_ci if (key->rounds == 12) { 1131cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 18); 1141cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 20); 1151cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 22); 1161cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 24); 1171cb0ef41Sopenharmony_ci } else if (key->rounds == 16) { 1181cb0ef41Sopenharmony_ci /* Do a full expansion to avoid a jump */ 1191cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 18); 1201cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 20); 1211cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 22); 1221cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 24); 1231cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 26); 1241cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 28); 1251cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 30); 1261cb0ef41Sopenharmony_ci E_RC5_32(a, b, s, 32); 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci d[0] = a; 1291cb0ef41Sopenharmony_ci d[1] = b; 1301cb0ef41Sopenharmony_ci} 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_civoid RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key) 1331cb0ef41Sopenharmony_ci{ 1341cb0ef41Sopenharmony_ci RC5_32_INT a, b, *s; 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci s = key->data; 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci a = d[0]; 1391cb0ef41Sopenharmony_ci b = d[1]; 1401cb0ef41Sopenharmony_ci if (key->rounds == 16) { 1411cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 32); 1421cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 30); 1431cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 28); 1441cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 26); 1451cb0ef41Sopenharmony_ci /* Do a full expansion to avoid a jump */ 1461cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 24); 1471cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 22); 1481cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 20); 1491cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 18); 1501cb0ef41Sopenharmony_ci } else if (key->rounds == 12) { 1511cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 24); 1521cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 22); 1531cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 20); 1541cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 18); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 16); 1571cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 14); 1581cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 12); 1591cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 10); 1601cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 8); 1611cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 6); 1621cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 4); 1631cb0ef41Sopenharmony_ci D_RC5_32(a, b, s, 2); 1641cb0ef41Sopenharmony_ci d[0] = a - s[0]; 1651cb0ef41Sopenharmony_ci d[1] = b - s[1]; 1661cb0ef41Sopenharmony_ci} 167