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