1// -*- mode:c++ -*- 2// 3// Copyright (c) 2018 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Matt Horsnell 39// Prakash Ramrakhyani 40 41let {{ 42 43 cryptoEnabledCheckCode = ''' 44 auto crypto_reg = xc->tcBase()->readMiscReg(MISCREG_ID_ISAR5); 45 if (!(crypto_reg & %(mask)d)) { 46 return std::make_shared<UndefinedInstruction>(machInst, true); 47 } 48 ''' 49 50 header_output = "" 51 decoder_output = "" 52 exec_output = "" 53 54 cryptoRegRegRegPrefix = ''' 55 Crypto crypto; 56 RegVect srcReg1, srcReg2, destReg; 57 // Read source and destination registers. 58 ''' 59 for reg in range(4): 60 cryptoRegRegRegPrefix += ''' 61 srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw); 62 srcReg2.regs[%(reg)d] = htog(FpOp2P%(reg)d_uw); 63 destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw); 64 ''' % { "reg" : reg } 65 cryptoRegRegRegPrefix += ''' 66 unsigned char *output = (unsigned char *)(&destReg.regs[0]); 67 unsigned char *input = (unsigned char *)(&srcReg1.regs[0]); 68 unsigned char *input2 = (unsigned char *)(&srcReg2.regs[0]); 69 ''' 70 71 cryptoSuffix = "" 72 for reg in range(4): 73 cryptoSuffix += ''' 74 FpDestP%(reg)d_uw = gtoh(destReg.regs[%(reg)d]); 75 ''' % { "reg" : reg } 76 77 cryptoRegRegPrefix = ''' 78 Crypto crypto; 79 RegVect srcReg1, destReg; 80 // Read source and destination registers. 81 ''' 82 for reg in range(4): 83 cryptoRegRegPrefix += ''' 84 srcReg1.regs[%(reg)d] = htog(FpOp1P%(reg)d_uw); 85 destReg.regs[%(reg)d] = htog(FpDestP%(reg)d_uw); 86 ''' % { "reg" : reg } 87 88 cryptoRegRegPrefix += ''' 89 // cast into format passed to aes encrypt method. 90 unsigned char *output = (unsigned char *)(&destReg.regs[0]); 91 unsigned char *input = (unsigned char *)(&srcReg1.regs[0]); 92 ''' 93 94 def cryptoRegRegRegInst(name, Name, opClass, enable_check, crypto_func): 95 global header_output, decoder_output, exec_output 96 97 crypto_prefix = enable_check + cryptoRegRegRegPrefix 98 cryptocode = crypto_prefix + crypto_func + cryptoSuffix 99 100 cryptoiop = InstObjParams(name, Name, "RegRegRegOp", 101 { "code": cryptocode, 102 "r_count": 4, 103 "predicate_test": predicateTest, 104 "op_class": opClass}, []) 105 header_output += RegRegRegOpDeclare.subst(cryptoiop) 106 decoder_output += RegRegRegOpConstructor.subst(cryptoiop) 107 exec_output += CryptoPredOpExecute.subst(cryptoiop) 108 109 def cryptoRegRegInst(name, Name, opClass, enable_check, crypto_func): 110 global header_output, decoder_output, exec_output 111 112 crypto_prefix = enable_check + cryptoRegRegPrefix 113 cryptocode = crypto_prefix + crypto_func + cryptoSuffix 114 115 cryptoiop = InstObjParams(name, Name, "RegRegOp", 116 { "code": cryptocode, 117 "r_count": 4, 118 "predicate_test": predicateTest, 119 "op_class": opClass}, []) 120 header_output += RegRegOpDeclare.subst(cryptoiop) 121 decoder_output += RegRegOpConstructor.subst(cryptoiop) 122 exec_output += CryptoPredOpExecute.subst(cryptoiop) 123 124 def cryptoRegRegImmInst(name, Name, opClass, enable_check, crypto_func): 125 global header_output, decoder_output, exec_output 126 127 crypto_prefix = enable_check + cryptoRegRegPrefix 128 cryptocode = crypto_prefix + crypto_func + cryptoSuffix 129 130 cryptoiop = InstObjParams(name, Name, "RegRegImmOp", 131 { "code": cryptocode, 132 "r_count": 4, 133 "predicate_test": predicateTest, 134 "op_class": opClass}, []) 135 header_output += RegRegImmOpDeclare.subst(cryptoiop) 136 decoder_output += RegRegImmOpConstructor.subst(cryptoiop) 137 exec_output += CryptoPredOpExecute.subst(cryptoiop) 138 139 aeseCode = "crypto.aesEncrypt(output, input, input2);" 140 aesdCode = "crypto.aesDecrypt(output, input, input2);" 141 aesmcCode = "crypto.aesMixColumns(output, input);" 142 aesimcCode = "crypto.aesInvMixColumns(output, input);" 143 144 sha1_cCode = "crypto.sha1C(output, input, input2);" 145 sha1_pCode = "crypto.sha1P(output, input, input2);" 146 sha1_mCode = "crypto.sha1M(output, input, input2);" 147 sha1_hCode = "crypto.sha1H(output, input);" 148 sha1_su0Code = "crypto.sha1Su0(output, input, input2);" 149 sha1_su1Code = "crypto.sha1Su1(output, input);" 150 151 sha256_hCode = "crypto.sha256H(output, input, input2);" 152 sha256_h2Code = "crypto.sha256H2(output, input, input2);" 153 sha256_su0Code = "crypto.sha256Su0(output, input);" 154 sha256_su1Code = "crypto.sha256Su1(output, input, input2);" 155 156 aes_enabled = cryptoEnabledCheckCode % { "mask" : 0xF0 } 157 cryptoRegRegRegInst("aese", "AESE", "SimdAesOp", 158 aes_enabled, aeseCode) 159 cryptoRegRegRegInst("aesd", "AESD", "SimdAesOp", 160 aes_enabled, aesdCode) 161 cryptoRegRegInst("aesmc", "AESMC", "SimdAesMixOp", 162 aes_enabled, aesmcCode) 163 cryptoRegRegInst("aesimc", "AESIMC", "SimdAesMixOp", 164 aes_enabled, aesimcCode) 165 166 sha1_enabled = cryptoEnabledCheckCode % { "mask" : 0xF00 } 167 cryptoRegRegRegInst("sha1c", "SHA1C", "SimdSha1HashOp", 168 sha1_enabled, sha1_cCode) 169 cryptoRegRegRegInst("sha1p", "SHA1P", "SimdSha1HashOp", 170 sha1_enabled, sha1_pCode) 171 cryptoRegRegRegInst("sha1m", "SHA1M", "SimdSha1HashOp", 172 sha1_enabled, sha1_mCode) 173 cryptoRegRegInst("sha1h", "SHA1H", "SimdSha1Hash2Op", 174 sha1_enabled, sha1_hCode) 175 cryptoRegRegRegInst("sha1su0", "SHA1SU0", "SimdShaSigma3Op", 176 sha1_enabled, sha1_su0Code) 177 cryptoRegRegInst("sha1su1", "SHA1SU1", "SimdShaSigma2Op", 178 sha1_enabled, sha1_su1Code) 179 180 sha2_enabled = cryptoEnabledCheckCode % { "mask" : 0xF000 } 181 cryptoRegRegRegInst("sha256h", "SHA256H", "SimdSha256HashOp", 182 sha2_enabled, sha256_hCode) 183 cryptoRegRegRegInst("sha256h2", "SHA256H2", "SimdSha256Hash2Op", 184 sha2_enabled, sha256_h2Code) 185 cryptoRegRegInst("sha256su0", "SHA256SU0", "SimdShaSigma2Op", 186 sha2_enabled, sha256_su0Code) 187 cryptoRegRegRegInst("sha256su1", "SHA256SU1", "SimdShaSigma3Op", 188 sha2_enabled, sha256_su1Code) 189}}; 190