1*68d19b58SWeiwei Li /* 2*68d19b58SWeiwei Li * RISC-V Crypto Emulation Helpers for QEMU. 3*68d19b58SWeiwei Li * 4*68d19b58SWeiwei Li * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com 5*68d19b58SWeiwei Li * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com 6*68d19b58SWeiwei Li * 7*68d19b58SWeiwei Li * This program is free software; you can redistribute it and/or modify it 8*68d19b58SWeiwei Li * under the terms and conditions of the GNU General Public License, 9*68d19b58SWeiwei Li * version 2 or later, as published by the Free Software Foundation. 10*68d19b58SWeiwei Li * 11*68d19b58SWeiwei Li * This program is distributed in the hope it will be useful, but WITHOUT 12*68d19b58SWeiwei Li * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*68d19b58SWeiwei Li * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14*68d19b58SWeiwei Li * more details. 15*68d19b58SWeiwei Li * 16*68d19b58SWeiwei Li * You should have received a copy of the GNU General Public License along with 17*68d19b58SWeiwei Li * this program. If not, see <http://www.gnu.org/licenses/>. 18*68d19b58SWeiwei Li */ 19*68d19b58SWeiwei Li 20*68d19b58SWeiwei Li #include "qemu/osdep.h" 21*68d19b58SWeiwei Li #include "cpu.h" 22*68d19b58SWeiwei Li #include "exec/exec-all.h" 23*68d19b58SWeiwei Li #include "exec/helper-proto.h" 24*68d19b58SWeiwei Li #include "crypto/aes.h" 25*68d19b58SWeiwei Li #include "crypto/sm4.h" 26*68d19b58SWeiwei Li 27*68d19b58SWeiwei Li #define AES_XTIME(a) \ 28*68d19b58SWeiwei Li ((a << 1) ^ ((a & 0x80) ? 0x1b : 0)) 29*68d19b58SWeiwei Li 30*68d19b58SWeiwei Li #define AES_GFMUL(a, b) (( \ 31*68d19b58SWeiwei Li (((b) & 0x1) ? (a) : 0) ^ \ 32*68d19b58SWeiwei Li (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \ 33*68d19b58SWeiwei Li (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \ 34*68d19b58SWeiwei Li (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF) 35*68d19b58SWeiwei Li 36*68d19b58SWeiwei Li static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd) 37*68d19b58SWeiwei Li { 38*68d19b58SWeiwei Li uint32_t u; 39*68d19b58SWeiwei Li 40*68d19b58SWeiwei Li if (fwd) { 41*68d19b58SWeiwei Li u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) | 42*68d19b58SWeiwei Li (AES_GFMUL(x, 2) << 0); 43*68d19b58SWeiwei Li } else { 44*68d19b58SWeiwei Li u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) | 45*68d19b58SWeiwei Li (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0); 46*68d19b58SWeiwei Li } 47*68d19b58SWeiwei Li return u; 48*68d19b58SWeiwei Li } 49*68d19b58SWeiwei Li 50*68d19b58SWeiwei Li #define sext32_xlen(x) (target_ulong)(int32_t)(x) 51*68d19b58SWeiwei Li 52*68d19b58SWeiwei Li static inline target_ulong aes32_operation(target_ulong shamt, 53*68d19b58SWeiwei Li target_ulong rs1, target_ulong rs2, 54*68d19b58SWeiwei Li bool enc, bool mix) 55*68d19b58SWeiwei Li { 56*68d19b58SWeiwei Li uint8_t si = rs2 >> shamt; 57*68d19b58SWeiwei Li uint8_t so; 58*68d19b58SWeiwei Li uint32_t mixed; 59*68d19b58SWeiwei Li target_ulong res; 60*68d19b58SWeiwei Li 61*68d19b58SWeiwei Li if (enc) { 62*68d19b58SWeiwei Li so = AES_sbox[si]; 63*68d19b58SWeiwei Li if (mix) { 64*68d19b58SWeiwei Li mixed = aes_mixcolumn_byte(so, true); 65*68d19b58SWeiwei Li } else { 66*68d19b58SWeiwei Li mixed = so; 67*68d19b58SWeiwei Li } 68*68d19b58SWeiwei Li } else { 69*68d19b58SWeiwei Li so = AES_isbox[si]; 70*68d19b58SWeiwei Li if (mix) { 71*68d19b58SWeiwei Li mixed = aes_mixcolumn_byte(so, false); 72*68d19b58SWeiwei Li } else { 73*68d19b58SWeiwei Li mixed = so; 74*68d19b58SWeiwei Li } 75*68d19b58SWeiwei Li } 76*68d19b58SWeiwei Li mixed = rol32(mixed, shamt); 77*68d19b58SWeiwei Li res = rs1 ^ mixed; 78*68d19b58SWeiwei Li 79*68d19b58SWeiwei Li return sext32_xlen(res); 80*68d19b58SWeiwei Li } 81*68d19b58SWeiwei Li 82*68d19b58SWeiwei Li target_ulong HELPER(aes32esmi)(target_ulong rs1, target_ulong rs2, 83*68d19b58SWeiwei Li target_ulong shamt) 84*68d19b58SWeiwei Li { 85*68d19b58SWeiwei Li return aes32_operation(shamt, rs1, rs2, true, true); 86*68d19b58SWeiwei Li } 87*68d19b58SWeiwei Li 88*68d19b58SWeiwei Li target_ulong HELPER(aes32esi)(target_ulong rs1, target_ulong rs2, 89*68d19b58SWeiwei Li target_ulong shamt) 90*68d19b58SWeiwei Li { 91*68d19b58SWeiwei Li return aes32_operation(shamt, rs1, rs2, true, false); 92*68d19b58SWeiwei Li } 93*68d19b58SWeiwei Li 94*68d19b58SWeiwei Li target_ulong HELPER(aes32dsmi)(target_ulong rs1, target_ulong rs2, 95*68d19b58SWeiwei Li target_ulong shamt) 96*68d19b58SWeiwei Li { 97*68d19b58SWeiwei Li return aes32_operation(shamt, rs1, rs2, false, true); 98*68d19b58SWeiwei Li } 99*68d19b58SWeiwei Li 100*68d19b58SWeiwei Li target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2, 101*68d19b58SWeiwei Li target_ulong shamt) 102*68d19b58SWeiwei Li { 103*68d19b58SWeiwei Li return aes32_operation(shamt, rs1, rs2, false, false); 104*68d19b58SWeiwei Li } 105*68d19b58SWeiwei Li #undef sext32_xlen 106