diff options
author | 2017-04-25 03:31:15 -0700 | |
---|---|---|
committer | 2017-05-22 06:48:08 +0000 | |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/crypto | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/crypto')
38 files changed, 0 insertions, 9614 deletions
diff --git a/qemu/crypto/Makefile.objs b/qemu/crypto/Makefile.objs deleted file mode 100644 index 0737f4811..000000000 --- a/qemu/crypto/Makefile.objs +++ /dev/null @@ -1,30 +0,0 @@ -crypto-obj-y = init.o -crypto-obj-y += hash.o -crypto-obj-y += aes.o -crypto-obj-y += desrfb.o -crypto-obj-y += cipher.o -crypto-obj-y += tlscreds.o -crypto-obj-y += tlscredsanon.o -crypto-obj-y += tlscredsx509.o -crypto-obj-y += tlssession.o -crypto-obj-y += secret.o -crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o -crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o -crypto-obj-y += pbkdf.o -crypto-obj-$(CONFIG_NETTLE_KDF) += pbkdf-nettle.o -crypto-obj-$(if $(CONFIG_NETTLE_KDF),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o -crypto-obj-y += ivgen.o -crypto-obj-y += ivgen-essiv.o -crypto-obj-y += ivgen-plain.o -crypto-obj-y += ivgen-plain64.o -crypto-obj-y += afsplit.o -crypto-obj-y += xts.o -crypto-obj-y += block.o -crypto-obj-y += block-qcow.o -crypto-obj-y += block-luks.o - -# Let the userspace emulators avoid linking gnutls/etc -crypto-aes-obj-y = aes.o - -stub-obj-y += random-stub.o -stub-obj-y += pbkdf-stub.o diff --git a/qemu/crypto/aes.c b/qemu/crypto/aes.c deleted file mode 100644 index 3456eacd0..000000000 --- a/qemu/crypto/aes.c +++ /dev/null @@ -1,1653 +0,0 @@ -/** - * - * aes.c - integrated in QEMU by Fabrice Bellard from the OpenSSL project. - */ -/* - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "qemu/osdep.h" -#include "qemu-common.h" -#include "crypto/aes.h" - -typedef uint32_t u32; -typedef uint8_t u8; - -/* This controls loop-unrolling in aes_core.c */ -#undef FULL_UNROLL -# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } - -const uint8_t AES_sbox[256] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, -}; - -const uint8_t AES_isbox[256] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D, -}; - -const uint8_t AES_shifts[16] = { - 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 -}; - -const uint8_t AES_ishifts[16] = { - 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 -}; - -/* AES_imc[x][0] = [x].[0e, 09, 0d, 0b]; */ -/* AES_imc[x][1] = [x].[0b, 0e, 09, 0d]; */ -/* AES_imc[x][2] = [x].[0d, 0b, 0e, 09]; */ -/* AES_imc[x][3] = [x].[09, 0d, 0b, 0e]; */ -const uint32_t AES_imc[256][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, /* x=00 */ - { 0x0E090D0B, 0x0B0E090D, 0x0D0B0E09, 0x090D0B0E, }, /* x=01 */ - { 0x1C121A16, 0x161C121A, 0x1A161C12, 0x121A161C, }, /* x=02 */ - { 0x121B171D, 0x1D121B17, 0x171D121B, 0x1B171D12, }, /* x=03 */ - { 0x3824342C, 0x2C382434, 0x342C3824, 0x24342C38, }, /* x=04 */ - { 0x362D3927, 0x27362D39, 0x3927362D, 0x2D392736, }, /* x=05 */ - { 0x24362E3A, 0x3A24362E, 0x2E3A2436, 0x362E3A24, }, /* x=06 */ - { 0x2A3F2331, 0x312A3F23, 0x23312A3F, 0x3F23312A, }, /* x=07 */ - { 0x70486858, 0x58704868, 0x68587048, 0x48685870, }, /* x=08 */ - { 0x7E416553, 0x537E4165, 0x65537E41, 0x4165537E, }, /* x=09 */ - { 0x6C5A724E, 0x4E6C5A72, 0x724E6C5A, 0x5A724E6C, }, /* x=0A */ - { 0x62537F45, 0x4562537F, 0x7F456253, 0x537F4562, }, /* x=0B */ - { 0x486C5C74, 0x74486C5C, 0x5C74486C, 0x6C5C7448, }, /* x=0C */ - { 0x4665517F, 0x7F466551, 0x517F4665, 0x65517F46, }, /* x=0D */ - { 0x547E4662, 0x62547E46, 0x4662547E, 0x7E466254, }, /* x=0E */ - { 0x5A774B69, 0x695A774B, 0x4B695A77, 0x774B695A, }, /* x=0F */ - { 0xE090D0B0, 0xB0E090D0, 0xD0B0E090, 0x90D0B0E0, }, /* x=10 */ - { 0xEE99DDBB, 0xBBEE99DD, 0xDDBBEE99, 0x99DDBBEE, }, /* x=11 */ - { 0xFC82CAA6, 0xA6FC82CA, 0xCAA6FC82, 0x82CAA6FC, }, /* x=12 */ - { 0xF28BC7AD, 0xADF28BC7, 0xC7ADF28B, 0x8BC7ADF2, }, /* x=13 */ - { 0xD8B4E49C, 0x9CD8B4E4, 0xE49CD8B4, 0xB4E49CD8, }, /* x=14 */ - { 0xD6BDE997, 0x97D6BDE9, 0xE997D6BD, 0xBDE997D6, }, /* x=15 */ - { 0xC4A6FE8A, 0x8AC4A6FE, 0xFE8AC4A6, 0xA6FE8AC4, }, /* x=16 */ - { 0xCAAFF381, 0x81CAAFF3, 0xF381CAAF, 0xAFF381CA, }, /* x=17 */ - { 0x90D8B8E8, 0xE890D8B8, 0xB8E890D8, 0xD8B8E890, }, /* x=18 */ - { 0x9ED1B5E3, 0xE39ED1B5, 0xB5E39ED1, 0xD1B5E39E, }, /* x=19 */ - { 0x8CCAA2FE, 0xFE8CCAA2, 0xA2FE8CCA, 0xCAA2FE8C, }, /* x=1A */ - { 0x82C3AFF5, 0xF582C3AF, 0xAFF582C3, 0xC3AFF582, }, /* x=1B */ - { 0xA8FC8CC4, 0xC4A8FC8C, 0x8CC4A8FC, 0xFC8CC4A8, }, /* x=1C */ - { 0xA6F581CF, 0xCFA6F581, 0x81CFA6F5, 0xF581CFA6, }, /* x=1D */ - { 0xB4EE96D2, 0xD2B4EE96, 0x96D2B4EE, 0xEE96D2B4, }, /* x=1E */ - { 0xBAE79BD9, 0xD9BAE79B, 0x9BD9BAE7, 0xE79BD9BA, }, /* x=1F */ - { 0xDB3BBB7B, 0x7BDB3BBB, 0xBB7BDB3B, 0x3BBB7BDB, }, /* x=20 */ - { 0xD532B670, 0x70D532B6, 0xB670D532, 0x32B670D5, }, /* x=21 */ - { 0xC729A16D, 0x6DC729A1, 0xA16DC729, 0x29A16DC7, }, /* x=22 */ - { 0xC920AC66, 0x66C920AC, 0xAC66C920, 0x20AC66C9, }, /* x=23 */ - { 0xE31F8F57, 0x57E31F8F, 0x8F57E31F, 0x1F8F57E3, }, /* x=24 */ - { 0xED16825C, 0x5CED1682, 0x825CED16, 0x16825CED, }, /* x=25 */ - { 0xFF0D9541, 0x41FF0D95, 0x9541FF0D, 0x0D9541FF, }, /* x=26 */ - { 0xF104984A, 0x4AF10498, 0x984AF104, 0x04984AF1, }, /* x=27 */ - { 0xAB73D323, 0x23AB73D3, 0xD323AB73, 0x73D323AB, }, /* x=28 */ - { 0xA57ADE28, 0x28A57ADE, 0xDE28A57A, 0x7ADE28A5, }, /* x=29 */ - { 0xB761C935, 0x35B761C9, 0xC935B761, 0x61C935B7, }, /* x=2A */ - { 0xB968C43E, 0x3EB968C4, 0xC43EB968, 0x68C43EB9, }, /* x=2B */ - { 0x9357E70F, 0x0F9357E7, 0xE70F9357, 0x57E70F93, }, /* x=2C */ - { 0x9D5EEA04, 0x049D5EEA, 0xEA049D5E, 0x5EEA049D, }, /* x=2D */ - { 0x8F45FD19, 0x198F45FD, 0xFD198F45, 0x45FD198F, }, /* x=2E */ - { 0x814CF012, 0x12814CF0, 0xF012814C, 0x4CF01281, }, /* x=2F */ - { 0x3BAB6BCB, 0xCB3BAB6B, 0x6BCB3BAB, 0xAB6BCB3B, }, /* x=30 */ - { 0x35A266C0, 0xC035A266, 0x66C035A2, 0xA266C035, }, /* x=31 */ - { 0x27B971DD, 0xDD27B971, 0x71DD27B9, 0xB971DD27, }, /* x=32 */ - { 0x29B07CD6, 0xD629B07C, 0x7CD629B0, 0xB07CD629, }, /* x=33 */ - { 0x038F5FE7, 0xE7038F5F, 0x5FE7038F, 0x8F5FE703, }, /* x=34 */ - { 0x0D8652EC, 0xEC0D8652, 0x52EC0D86, 0x8652EC0D, }, /* x=35 */ - { 0x1F9D45F1, 0xF11F9D45, 0x45F11F9D, 0x9D45F11F, }, /* x=36 */ - { 0x119448FA, 0xFA119448, 0x48FA1194, 0x9448FA11, }, /* x=37 */ - { 0x4BE30393, 0x934BE303, 0x03934BE3, 0xE303934B, }, /* x=38 */ - { 0x45EA0E98, 0x9845EA0E, 0x0E9845EA, 0xEA0E9845, }, /* x=39 */ - { 0x57F11985, 0x8557F119, 0x198557F1, 0xF1198557, }, /* x=3A */ - { 0x59F8148E, 0x8E59F814, 0x148E59F8, 0xF8148E59, }, /* x=3B */ - { 0x73C737BF, 0xBF73C737, 0x37BF73C7, 0xC737BF73, }, /* x=3C */ - { 0x7DCE3AB4, 0xB47DCE3A, 0x3AB47DCE, 0xCE3AB47D, }, /* x=3D */ - { 0x6FD52DA9, 0xA96FD52D, 0x2DA96FD5, 0xD52DA96F, }, /* x=3E */ - { 0x61DC20A2, 0xA261DC20, 0x20A261DC, 0xDC20A261, }, /* x=3F */ - { 0xAD766DF6, 0xF6AD766D, 0x6DF6AD76, 0x766DF6AD, }, /* x=40 */ - { 0xA37F60FD, 0xFDA37F60, 0x60FDA37F, 0x7F60FDA3, }, /* x=41 */ - { 0xB16477E0, 0xE0B16477, 0x77E0B164, 0x6477E0B1, }, /* x=42 */ - { 0xBF6D7AEB, 0xEBBF6D7A, 0x7AEBBF6D, 0x6D7AEBBF, }, /* x=43 */ - { 0x955259DA, 0xDA955259, 0x59DA9552, 0x5259DA95, }, /* x=44 */ - { 0x9B5B54D1, 0xD19B5B54, 0x54D19B5B, 0x5B54D19B, }, /* x=45 */ - { 0x894043CC, 0xCC894043, 0x43CC8940, 0x4043CC89, }, /* x=46 */ - { 0x87494EC7, 0xC787494E, 0x4EC78749, 0x494EC787, }, /* x=47 */ - { 0xDD3E05AE, 0xAEDD3E05, 0x05AEDD3E, 0x3E05AEDD, }, /* x=48 */ - { 0xD33708A5, 0xA5D33708, 0x08A5D337, 0x3708A5D3, }, /* x=49 */ - { 0xC12C1FB8, 0xB8C12C1F, 0x1FB8C12C, 0x2C1FB8C1, }, /* x=4A */ - { 0xCF2512B3, 0xB3CF2512, 0x12B3CF25, 0x2512B3CF, }, /* x=4B */ - { 0xE51A3182, 0x82E51A31, 0x3182E51A, 0x1A3182E5, }, /* x=4C */ - { 0xEB133C89, 0x89EB133C, 0x3C89EB13, 0x133C89EB, }, /* x=4D */ - { 0xF9082B94, 0x94F9082B, 0x2B94F908, 0x082B94F9, }, /* x=4E */ - { 0xF701269F, 0x9FF70126, 0x269FF701, 0x01269FF7, }, /* x=4F */ - { 0x4DE6BD46, 0x464DE6BD, 0xBD464DE6, 0xE6BD464D, }, /* x=50 */ - { 0x43EFB04D, 0x4D43EFB0, 0xB04D43EF, 0xEFB04D43, }, /* x=51 */ - { 0x51F4A750, 0x5051F4A7, 0xA75051F4, 0xF4A75051, }, /* x=52 */ - { 0x5FFDAA5B, 0x5B5FFDAA, 0xAA5B5FFD, 0xFDAA5B5F, }, /* x=53 */ - { 0x75C2896A, 0x6A75C289, 0x896A75C2, 0xC2896A75, }, /* x=54 */ - { 0x7BCB8461, 0x617BCB84, 0x84617BCB, 0xCB84617B, }, /* x=55 */ - { 0x69D0937C, 0x7C69D093, 0x937C69D0, 0xD0937C69, }, /* x=56 */ - { 0x67D99E77, 0x7767D99E, 0x9E7767D9, 0xD99E7767, }, /* x=57 */ - { 0x3DAED51E, 0x1E3DAED5, 0xD51E3DAE, 0xAED51E3D, }, /* x=58 */ - { 0x33A7D815, 0x1533A7D8, 0xD81533A7, 0xA7D81533, }, /* x=59 */ - { 0x21BCCF08, 0x0821BCCF, 0xCF0821BC, 0xBCCF0821, }, /* x=5A */ - { 0x2FB5C203, 0x032FB5C2, 0xC2032FB5, 0xB5C2032F, }, /* x=5B */ - { 0x058AE132, 0x32058AE1, 0xE132058A, 0x8AE13205, }, /* x=5C */ - { 0x0B83EC39, 0x390B83EC, 0xEC390B83, 0x83EC390B, }, /* x=5D */ - { 0x1998FB24, 0x241998FB, 0xFB241998, 0x98FB2419, }, /* x=5E */ - { 0x1791F62F, 0x2F1791F6, 0xF62F1791, 0x91F62F17, }, /* x=5F */ - { 0x764DD68D, 0x8D764DD6, 0xD68D764D, 0x4DD68D76, }, /* x=60 */ - { 0x7844DB86, 0x867844DB, 0xDB867844, 0x44DB8678, }, /* x=61 */ - { 0x6A5FCC9B, 0x9B6A5FCC, 0xCC9B6A5F, 0x5FCC9B6A, }, /* x=62 */ - { 0x6456C190, 0x906456C1, 0xC1906456, 0x56C19064, }, /* x=63 */ - { 0x4E69E2A1, 0xA14E69E2, 0xE2A14E69, 0x69E2A14E, }, /* x=64 */ - { 0x4060EFAA, 0xAA4060EF, 0xEFAA4060, 0x60EFAA40, }, /* x=65 */ - { 0x527BF8B7, 0xB7527BF8, 0xF8B7527B, 0x7BF8B752, }, /* x=66 */ - { 0x5C72F5BC, 0xBC5C72F5, 0xF5BC5C72, 0x72F5BC5C, }, /* x=67 */ - { 0x0605BED5, 0xD50605BE, 0xBED50605, 0x05BED506, }, /* x=68 */ - { 0x080CB3DE, 0xDE080CB3, 0xB3DE080C, 0x0CB3DE08, }, /* x=69 */ - { 0x1A17A4C3, 0xC31A17A4, 0xA4C31A17, 0x17A4C31A, }, /* x=6A */ - { 0x141EA9C8, 0xC8141EA9, 0xA9C8141E, 0x1EA9C814, }, /* x=6B */ - { 0x3E218AF9, 0xF93E218A, 0x8AF93E21, 0x218AF93E, }, /* x=6C */ - { 0x302887F2, 0xF2302887, 0x87F23028, 0x2887F230, }, /* x=6D */ - { 0x223390EF, 0xEF223390, 0x90EF2233, 0x3390EF22, }, /* x=6E */ - { 0x2C3A9DE4, 0xE42C3A9D, 0x9DE42C3A, 0x3A9DE42C, }, /* x=6F */ - { 0x96DD063D, 0x3D96DD06, 0x063D96DD, 0xDD063D96, }, /* x=70 */ - { 0x98D40B36, 0x3698D40B, 0x0B3698D4, 0xD40B3698, }, /* x=71 */ - { 0x8ACF1C2B, 0x2B8ACF1C, 0x1C2B8ACF, 0xCF1C2B8A, }, /* x=72 */ - { 0x84C61120, 0x2084C611, 0x112084C6, 0xC6112084, }, /* x=73 */ - { 0xAEF93211, 0x11AEF932, 0x3211AEF9, 0xF93211AE, }, /* x=74 */ - { 0xA0F03F1A, 0x1AA0F03F, 0x3F1AA0F0, 0xF03F1AA0, }, /* x=75 */ - { 0xB2EB2807, 0x07B2EB28, 0x2807B2EB, 0xEB2807B2, }, /* x=76 */ - { 0xBCE2250C, 0x0CBCE225, 0x250CBCE2, 0xE2250CBC, }, /* x=77 */ - { 0xE6956E65, 0x65E6956E, 0x6E65E695, 0x956E65E6, }, /* x=78 */ - { 0xE89C636E, 0x6EE89C63, 0x636EE89C, 0x9C636EE8, }, /* x=79 */ - { 0xFA877473, 0x73FA8774, 0x7473FA87, 0x877473FA, }, /* x=7A */ - { 0xF48E7978, 0x78F48E79, 0x7978F48E, 0x8E7978F4, }, /* x=7B */ - { 0xDEB15A49, 0x49DEB15A, 0x5A49DEB1, 0xB15A49DE, }, /* x=7C */ - { 0xD0B85742, 0x42D0B857, 0x5742D0B8, 0xB85742D0, }, /* x=7D */ - { 0xC2A3405F, 0x5FC2A340, 0x405FC2A3, 0xA3405FC2, }, /* x=7E */ - { 0xCCAA4D54, 0x54CCAA4D, 0x4D54CCAA, 0xAA4D54CC, }, /* x=7F */ - { 0x41ECDAF7, 0xF741ECDA, 0xDAF741EC, 0xECDAF741, }, /* x=80 */ - { 0x4FE5D7FC, 0xFC4FE5D7, 0xD7FC4FE5, 0xE5D7FC4F, }, /* x=81 */ - { 0x5DFEC0E1, 0xE15DFEC0, 0xC0E15DFE, 0xFEC0E15D, }, /* x=82 */ - { 0x53F7CDEA, 0xEA53F7CD, 0xCDEA53F7, 0xF7CDEA53, }, /* x=83 */ - { 0x79C8EEDB, 0xDB79C8EE, 0xEEDB79C8, 0xC8EEDB79, }, /* x=84 */ - { 0x77C1E3D0, 0xD077C1E3, 0xE3D077C1, 0xC1E3D077, }, /* x=85 */ - { 0x65DAF4CD, 0xCD65DAF4, 0xF4CD65DA, 0xDAF4CD65, }, /* x=86 */ - { 0x6BD3F9C6, 0xC66BD3F9, 0xF9C66BD3, 0xD3F9C66B, }, /* x=87 */ - { 0x31A4B2AF, 0xAF31A4B2, 0xB2AF31A4, 0xA4B2AF31, }, /* x=88 */ - { 0x3FADBFA4, 0xA43FADBF, 0xBFA43FAD, 0xADBFA43F, }, /* x=89 */ - { 0x2DB6A8B9, 0xB92DB6A8, 0xA8B92DB6, 0xB6A8B92D, }, /* x=8A */ - { 0x23BFA5B2, 0xB223BFA5, 0xA5B223BF, 0xBFA5B223, }, /* x=8B */ - { 0x09808683, 0x83098086, 0x86830980, 0x80868309, }, /* x=8C */ - { 0x07898B88, 0x8807898B, 0x8B880789, 0x898B8807, }, /* x=8D */ - { 0x15929C95, 0x9515929C, 0x9C951592, 0x929C9515, }, /* x=8E */ - { 0x1B9B919E, 0x9E1B9B91, 0x919E1B9B, 0x9B919E1B, }, /* x=8F */ - { 0xA17C0A47, 0x47A17C0A, 0x0A47A17C, 0x7C0A47A1, }, /* x=90 */ - { 0xAF75074C, 0x4CAF7507, 0x074CAF75, 0x75074CAF, }, /* x=91 */ - { 0xBD6E1051, 0x51BD6E10, 0x1051BD6E, 0x6E1051BD, }, /* x=92 */ - { 0xB3671D5A, 0x5AB3671D, 0x1D5AB367, 0x671D5AB3, }, /* x=93 */ - { 0x99583E6B, 0x6B99583E, 0x3E6B9958, 0x583E6B99, }, /* x=94 */ - { 0x97513360, 0x60975133, 0x33609751, 0x51336097, }, /* x=95 */ - { 0x854A247D, 0x7D854A24, 0x247D854A, 0x4A247D85, }, /* x=96 */ - { 0x8B432976, 0x768B4329, 0x29768B43, 0x4329768B, }, /* x=97 */ - { 0xD134621F, 0x1FD13462, 0x621FD134, 0x34621FD1, }, /* x=98 */ - { 0xDF3D6F14, 0x14DF3D6F, 0x6F14DF3D, 0x3D6F14DF, }, /* x=99 */ - { 0xCD267809, 0x09CD2678, 0x7809CD26, 0x267809CD, }, /* x=9A */ - { 0xC32F7502, 0x02C32F75, 0x7502C32F, 0x2F7502C3, }, /* x=9B */ - { 0xE9105633, 0x33E91056, 0x5633E910, 0x105633E9, }, /* x=9C */ - { 0xE7195B38, 0x38E7195B, 0x5B38E719, 0x195B38E7, }, /* x=9D */ - { 0xF5024C25, 0x25F5024C, 0x4C25F502, 0x024C25F5, }, /* x=9E */ - { 0xFB0B412E, 0x2EFB0B41, 0x412EFB0B, 0x0B412EFB, }, /* x=9F */ - { 0x9AD7618C, 0x8C9AD761, 0x618C9AD7, 0xD7618C9A, }, /* x=A0 */ - { 0x94DE6C87, 0x8794DE6C, 0x6C8794DE, 0xDE6C8794, }, /* x=A1 */ - { 0x86C57B9A, 0x9A86C57B, 0x7B9A86C5, 0xC57B9A86, }, /* x=A2 */ - { 0x88CC7691, 0x9188CC76, 0x769188CC, 0xCC769188, }, /* x=A3 */ - { 0xA2F355A0, 0xA0A2F355, 0x55A0A2F3, 0xF355A0A2, }, /* x=A4 */ - { 0xACFA58AB, 0xABACFA58, 0x58ABACFA, 0xFA58ABAC, }, /* x=A5 */ - { 0xBEE14FB6, 0xB6BEE14F, 0x4FB6BEE1, 0xE14FB6BE, }, /* x=A6 */ - { 0xB0E842BD, 0xBDB0E842, 0x42BDB0E8, 0xE842BDB0, }, /* x=A7 */ - { 0xEA9F09D4, 0xD4EA9F09, 0x09D4EA9F, 0x9F09D4EA, }, /* x=A8 */ - { 0xE49604DF, 0xDFE49604, 0x04DFE496, 0x9604DFE4, }, /* x=A9 */ - { 0xF68D13C2, 0xC2F68D13, 0x13C2F68D, 0x8D13C2F6, }, /* x=AA */ - { 0xF8841EC9, 0xC9F8841E, 0x1EC9F884, 0x841EC9F8, }, /* x=AB */ - { 0xD2BB3DF8, 0xF8D2BB3D, 0x3DF8D2BB, 0xBB3DF8D2, }, /* x=AC */ - { 0xDCB230F3, 0xF3DCB230, 0x30F3DCB2, 0xB230F3DC, }, /* x=AD */ - { 0xCEA927EE, 0xEECEA927, 0x27EECEA9, 0xA927EECE, }, /* x=AE */ - { 0xC0A02AE5, 0xE5C0A02A, 0x2AE5C0A0, 0xA02AE5C0, }, /* x=AF */ - { 0x7A47B13C, 0x3C7A47B1, 0xB13C7A47, 0x47B13C7A, }, /* x=B0 */ - { 0x744EBC37, 0x37744EBC, 0xBC37744E, 0x4EBC3774, }, /* x=B1 */ - { 0x6655AB2A, 0x2A6655AB, 0xAB2A6655, 0x55AB2A66, }, /* x=B2 */ - { 0x685CA621, 0x21685CA6, 0xA621685C, 0x5CA62168, }, /* x=B3 */ - { 0x42638510, 0x10426385, 0x85104263, 0x63851042, }, /* x=B4 */ - { 0x4C6A881B, 0x1B4C6A88, 0x881B4C6A, 0x6A881B4C, }, /* x=B5 */ - { 0x5E719F06, 0x065E719F, 0x9F065E71, 0x719F065E, }, /* x=B6 */ - { 0x5078920D, 0x0D507892, 0x920D5078, 0x78920D50, }, /* x=B7 */ - { 0x0A0FD964, 0x640A0FD9, 0xD9640A0F, 0x0FD9640A, }, /* x=B8 */ - { 0x0406D46F, 0x6F0406D4, 0xD46F0406, 0x06D46F04, }, /* x=B9 */ - { 0x161DC372, 0x72161DC3, 0xC372161D, 0x1DC37216, }, /* x=BA */ - { 0x1814CE79, 0x791814CE, 0xCE791814, 0x14CE7918, }, /* x=BB */ - { 0x322BED48, 0x48322BED, 0xED48322B, 0x2BED4832, }, /* x=BC */ - { 0x3C22E043, 0x433C22E0, 0xE0433C22, 0x22E0433C, }, /* x=BD */ - { 0x2E39F75E, 0x5E2E39F7, 0xF75E2E39, 0x39F75E2E, }, /* x=BE */ - { 0x2030FA55, 0x552030FA, 0xFA552030, 0x30FA5520, }, /* x=BF */ - { 0xEC9AB701, 0x01EC9AB7, 0xB701EC9A, 0x9AB701EC, }, /* x=C0 */ - { 0xE293BA0A, 0x0AE293BA, 0xBA0AE293, 0x93BA0AE2, }, /* x=C1 */ - { 0xF088AD17, 0x17F088AD, 0xAD17F088, 0x88AD17F0, }, /* x=C2 */ - { 0xFE81A01C, 0x1CFE81A0, 0xA01CFE81, 0x81A01CFE, }, /* x=C3 */ - { 0xD4BE832D, 0x2DD4BE83, 0x832DD4BE, 0xBE832DD4, }, /* x=C4 */ - { 0xDAB78E26, 0x26DAB78E, 0x8E26DAB7, 0xB78E26DA, }, /* x=C5 */ - { 0xC8AC993B, 0x3BC8AC99, 0x993BC8AC, 0xAC993BC8, }, /* x=C6 */ - { 0xC6A59430, 0x30C6A594, 0x9430C6A5, 0xA59430C6, }, /* x=C7 */ - { 0x9CD2DF59, 0x599CD2DF, 0xDF599CD2, 0xD2DF599C, }, /* x=C8 */ - { 0x92DBD252, 0x5292DBD2, 0xD25292DB, 0xDBD25292, }, /* x=C9 */ - { 0x80C0C54F, 0x4F80C0C5, 0xC54F80C0, 0xC0C54F80, }, /* x=CA */ - { 0x8EC9C844, 0x448EC9C8, 0xC8448EC9, 0xC9C8448E, }, /* x=CB */ - { 0xA4F6EB75, 0x75A4F6EB, 0xEB75A4F6, 0xF6EB75A4, }, /* x=CC */ - { 0xAAFFE67E, 0x7EAAFFE6, 0xE67EAAFF, 0xFFE67EAA, }, /* x=CD */ - { 0xB8E4F163, 0x63B8E4F1, 0xF163B8E4, 0xE4F163B8, }, /* x=CE */ - { 0xB6EDFC68, 0x68B6EDFC, 0xFC68B6ED, 0xEDFC68B6, }, /* x=CF */ - { 0x0C0A67B1, 0xB10C0A67, 0x67B10C0A, 0x0A67B10C, }, /* x=D0 */ - { 0x02036ABA, 0xBA02036A, 0x6ABA0203, 0x036ABA02, }, /* x=D1 */ - { 0x10187DA7, 0xA710187D, 0x7DA71018, 0x187DA710, }, /* x=D2 */ - { 0x1E1170AC, 0xAC1E1170, 0x70AC1E11, 0x1170AC1E, }, /* x=D3 */ - { 0x342E539D, 0x9D342E53, 0x539D342E, 0x2E539D34, }, /* x=D4 */ - { 0x3A275E96, 0x963A275E, 0x5E963A27, 0x275E963A, }, /* x=D5 */ - { 0x283C498B, 0x8B283C49, 0x498B283C, 0x3C498B28, }, /* x=D6 */ - { 0x26354480, 0x80263544, 0x44802635, 0x35448026, }, /* x=D7 */ - { 0x7C420FE9, 0xE97C420F, 0x0FE97C42, 0x420FE97C, }, /* x=D8 */ - { 0x724B02E2, 0xE2724B02, 0x02E2724B, 0x4B02E272, }, /* x=D9 */ - { 0x605015FF, 0xFF605015, 0x15FF6050, 0x5015FF60, }, /* x=DA */ - { 0x6E5918F4, 0xF46E5918, 0x18F46E59, 0x5918F46E, }, /* x=DB */ - { 0x44663BC5, 0xC544663B, 0x3BC54466, 0x663BC544, }, /* x=DC */ - { 0x4A6F36CE, 0xCE4A6F36, 0x36CE4A6F, 0x6F36CE4A, }, /* x=DD */ - { 0x587421D3, 0xD3587421, 0x21D35874, 0x7421D358, }, /* x=DE */ - { 0x567D2CD8, 0xD8567D2C, 0x2CD8567D, 0x7D2CD856, }, /* x=DF */ - { 0x37A10C7A, 0x7A37A10C, 0x0C7A37A1, 0xA10C7A37, }, /* x=E0 */ - { 0x39A80171, 0x7139A801, 0x017139A8, 0xA8017139, }, /* x=E1 */ - { 0x2BB3166C, 0x6C2BB316, 0x166C2BB3, 0xB3166C2B, }, /* x=E2 */ - { 0x25BA1B67, 0x6725BA1B, 0x1B6725BA, 0xBA1B6725, }, /* x=E3 */ - { 0x0F853856, 0x560F8538, 0x38560F85, 0x8538560F, }, /* x=E4 */ - { 0x018C355D, 0x5D018C35, 0x355D018C, 0x8C355D01, }, /* x=E5 */ - { 0x13972240, 0x40139722, 0x22401397, 0x97224013, }, /* x=E6 */ - { 0x1D9E2F4B, 0x4B1D9E2F, 0x2F4B1D9E, 0x9E2F4B1D, }, /* x=E7 */ - { 0x47E96422, 0x2247E964, 0x642247E9, 0xE9642247, }, /* x=E8 */ - { 0x49E06929, 0x2949E069, 0x692949E0, 0xE0692949, }, /* x=E9 */ - { 0x5BFB7E34, 0x345BFB7E, 0x7E345BFB, 0xFB7E345B, }, /* x=EA */ - { 0x55F2733F, 0x3F55F273, 0x733F55F2, 0xF2733F55, }, /* x=EB */ - { 0x7FCD500E, 0x0E7FCD50, 0x500E7FCD, 0xCD500E7F, }, /* x=EC */ - { 0x71C45D05, 0x0571C45D, 0x5D0571C4, 0xC45D0571, }, /* x=ED */ - { 0x63DF4A18, 0x1863DF4A, 0x4A1863DF, 0xDF4A1863, }, /* x=EE */ - { 0x6DD64713, 0x136DD647, 0x47136DD6, 0xD647136D, }, /* x=EF */ - { 0xD731DCCA, 0xCAD731DC, 0xDCCAD731, 0x31DCCAD7, }, /* x=F0 */ - { 0xD938D1C1, 0xC1D938D1, 0xD1C1D938, 0x38D1C1D9, }, /* x=F1 */ - { 0xCB23C6DC, 0xDCCB23C6, 0xC6DCCB23, 0x23C6DCCB, }, /* x=F2 */ - { 0xC52ACBD7, 0xD7C52ACB, 0xCBD7C52A, 0x2ACBD7C5, }, /* x=F3 */ - { 0xEF15E8E6, 0xE6EF15E8, 0xE8E6EF15, 0x15E8E6EF, }, /* x=F4 */ - { 0xE11CE5ED, 0xEDE11CE5, 0xE5EDE11C, 0x1CE5EDE1, }, /* x=F5 */ - { 0xF307F2F0, 0xF0F307F2, 0xF2F0F307, 0x07F2F0F3, }, /* x=F6 */ - { 0xFD0EFFFB, 0xFBFD0EFF, 0xFFFBFD0E, 0x0EFFFBFD, }, /* x=F7 */ - { 0xA779B492, 0x92A779B4, 0xB492A779, 0x79B492A7, }, /* x=F8 */ - { 0xA970B999, 0x99A970B9, 0xB999A970, 0x70B999A9, }, /* x=F9 */ - { 0xBB6BAE84, 0x84BB6BAE, 0xAE84BB6B, 0x6BAE84BB, }, /* x=FA */ - { 0xB562A38F, 0x8FB562A3, 0xA38FB562, 0x62A38FB5, }, /* x=FB */ - { 0x9F5D80BE, 0xBE9F5D80, 0x80BE9F5D, 0x5D80BE9F, }, /* x=FC */ - { 0x91548DB5, 0xB591548D, 0x8DB59154, 0x548DB591, }, /* x=FD */ - { 0x834F9AA8, 0xA8834F9A, 0x9AA8834F, 0x4F9AA883, }, /* x=FE */ - { 0x8D4697A3, 0xA38D4697, 0x97A38D46, 0x4697A38D, }, /* x=FF */ -}; - - - -/* -AES_Te0[x] = S [x].[02, 01, 01, 03]; -AES_Te1[x] = S [x].[03, 02, 01, 01]; -AES_Te2[x] = S [x].[01, 03, 02, 01]; -AES_Te3[x] = S [x].[01, 01, 03, 02]; -AES_Te4[x] = S [x].[01, 01, 01, 01]; - -AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; -AES_Td1[x] = Si[x].[0b, 0e, 09, 0d]; -AES_Td2[x] = Si[x].[0d, 0b, 0e, 09]; -AES_Td3[x] = Si[x].[09, 0d, 0b, 0e]; -AES_Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -const uint32_t AES_Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -const uint32_t AES_Te1[256] = { - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -const uint32_t AES_Te2[256] = { - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -const uint32_t AES_Te3[256] = { - - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; -const uint32_t AES_Te4[256] = { - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; -const uint32_t AES_Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -const uint32_t AES_Td1[256] = { - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -const uint32_t AES_Td2[256] = { - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -const uint32_t AES_Td3[256] = { - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -const uint32_t AES_Td4[256] = { - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, -}; -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - */ -int AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) { - - u32 *rk; - int i = 0; - u32 temp; - - if (!userKey || !key) - return -1; - if (bits != 128 && bits != 192 && bits != 256) - return -2; - - rk = key->rd_key; - - if (bits==128) - key->rounds = 10; - else if (bits==192) - key->rounds = 12; - else - key->rounds = 14; - - rk[0] = GETU32(userKey ); - rk[1] = GETU32(userKey + 4); - rk[2] = GETU32(userKey + 8); - rk[3] = GETU32(userKey + 12); - if (bits == 128) { - while (1) { - temp = rk[3]; - rk[4] = rk[0] ^ - (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 0; - } - rk += 4; - } - } - rk[4] = GETU32(userKey + 16); - rk[5] = GETU32(userKey + 20); - if (bits == 192) { - while (1) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 0; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(userKey + 24); - rk[7] = GETU32(userKey + 28); - if (bits == 256) { - while (1) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 0; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (AES_Te4[(temp >> 24) ] & 0xff000000) ^ - (AES_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - abort(); -} - -/** - * Expand the cipher key into the decryption key schedule. - */ -int AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) { - - u32 *rk; - int i, j, status; - u32 temp; - - /* first, start with an encryption schedule */ - status = AES_set_encrypt_key(userKey, bits, key); - if (status < 0) - return status; - - rk = key->rd_key; - - /* invert the order of the round keys: */ - for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < (key->rounds); i++) { - rk += 4; - rk[0] = - AES_Td0[AES_Te4[(rk[0] >> 24) ] & 0xff] ^ - AES_Td1[AES_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - AES_Td2[AES_Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - AES_Td3[AES_Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - AES_Td0[AES_Te4[(rk[1] >> 24) ] & 0xff] ^ - AES_Td1[AES_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - AES_Td2[AES_Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - AES_Td3[AES_Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - AES_Td0[AES_Te4[(rk[2] >> 24) ] & 0xff] ^ - AES_Td1[AES_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - AES_Td2[AES_Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - AES_Td3[AES_Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - AES_Td0[AES_Te4[(rk[3] >> 24) ] & 0xff] ^ - AES_Td1[AES_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - AES_Td2[AES_Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - AES_Td3[AES_Te4[(rk[3] ) & 0xff] & 0xff]; - } - return 0; -} - -#ifndef AES_ASM -/* - * Encrypt a single block - * in and out can overlap - */ -void AES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) { - - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - assert(in && out && key); - rk = key->rd_key; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(in ) ^ rk[0]; - s1 = GETU32(in + 4) ^ rk[1]; - s2 = GETU32(in + 8) ^ rk[2]; - s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[ 4]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[ 5]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[ 6]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[ 8]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[ 9]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[10]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[12]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[13]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[14]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[16]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[17]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[18]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[20]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[21]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[22]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[24]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[25]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[26]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[28]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[29]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[30]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[32]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[33]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[34]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[36]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[37]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[38]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[39]; - if (key->rounds > 10) { - /* round 10: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[40]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[41]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[42]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[44]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[45]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[46]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[47]; - if (key->rounds > 12) { - /* round 12: */ - s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[48]; - s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[49]; - s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[50]; - s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[52]; - t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[53]; - t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[54]; - t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[55]; - } - } - rk += key->rounds << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = key->rounds >> 1; - for (;;) { - t0 = - AES_Te0[(s0 >> 24) ] ^ - AES_Te1[(s1 >> 16) & 0xff] ^ - AES_Te2[(s2 >> 8) & 0xff] ^ - AES_Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - AES_Te0[(s1 >> 24) ] ^ - AES_Te1[(s2 >> 16) & 0xff] ^ - AES_Te2[(s3 >> 8) & 0xff] ^ - AES_Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - AES_Te0[(s2 >> 24) ] ^ - AES_Te1[(s3 >> 16) & 0xff] ^ - AES_Te2[(s0 >> 8) & 0xff] ^ - AES_Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - AES_Te0[(s3 >> 24) ] ^ - AES_Te1[(s0 >> 16) & 0xff] ^ - AES_Te2[(s1 >> 8) & 0xff] ^ - AES_Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - AES_Te0[(t0 >> 24) ] ^ - AES_Te1[(t1 >> 16) & 0xff] ^ - AES_Te2[(t2 >> 8) & 0xff] ^ - AES_Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - AES_Te0[(t1 >> 24) ] ^ - AES_Te1[(t2 >> 16) & 0xff] ^ - AES_Te2[(t3 >> 8) & 0xff] ^ - AES_Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - AES_Te0[(t2 >> 24) ] ^ - AES_Te1[(t3 >> 16) & 0xff] ^ - AES_Te2[(t0 >> 8) & 0xff] ^ - AES_Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - AES_Te0[(t3 >> 24) ] ^ - AES_Te1[(t0 >> 16) & 0xff] ^ - AES_Te2[(t1 >> 8) & 0xff] ^ - AES_Te3[(t2 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (AES_Te4[(t0 >> 24) ] & 0xff000000) ^ - (AES_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(out , s0); - s1 = - (AES_Te4[(t1 >> 24) ] & 0xff000000) ^ - (AES_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = - (AES_Te4[(t2 >> 24) ] & 0xff000000) ^ - (AES_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = - (AES_Te4[(t3 >> 24) ] & 0xff000000) ^ - (AES_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(out + 12, s3); -} - -/* - * Decrypt a single block - * in and out can overlap - */ -void AES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) { - - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - assert(in && out && key); - rk = key->rd_key; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(in ) ^ rk[0]; - s1 = GETU32(in + 4) ^ rk[1]; - s2 = GETU32(in + 8) ^ rk[2]; - s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[ 4]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[ 5]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[ 6]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[ 8]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[ 9]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[10]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[12]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[13]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[14]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[16]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[17]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[18]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[20]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[21]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[22]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[24]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[25]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[26]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[28]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[29]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[30]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[32]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[33]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[34]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[36]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[37]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[38]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[39]; - if (key->rounds > 10) { - /* round 10: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[40]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[41]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[42]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[44]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[45]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[46]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[47]; - if (key->rounds > 12) { - /* round 12: */ - s0 = AES_Td0[t0 >> 24] ^ AES_Td1[(t3 >> 16) & 0xff] ^ AES_Td2[(t2 >> 8) & 0xff] ^ AES_Td3[t1 & 0xff] ^ rk[48]; - s1 = AES_Td0[t1 >> 24] ^ AES_Td1[(t0 >> 16) & 0xff] ^ AES_Td2[(t3 >> 8) & 0xff] ^ AES_Td3[t2 & 0xff] ^ rk[49]; - s2 = AES_Td0[t2 >> 24] ^ AES_Td1[(t1 >> 16) & 0xff] ^ AES_Td2[(t0 >> 8) & 0xff] ^ AES_Td3[t3 & 0xff] ^ rk[50]; - s3 = AES_Td0[t3 >> 24] ^ AES_Td1[(t2 >> 16) & 0xff] ^ AES_Td2[(t1 >> 8) & 0xff] ^ AES_Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = AES_Td0[s0 >> 24] ^ AES_Td1[(s3 >> 16) & 0xff] ^ AES_Td2[(s2 >> 8) & 0xff] ^ AES_Td3[s1 & 0xff] ^ rk[52]; - t1 = AES_Td0[s1 >> 24] ^ AES_Td1[(s0 >> 16) & 0xff] ^ AES_Td2[(s3 >> 8) & 0xff] ^ AES_Td3[s2 & 0xff] ^ rk[53]; - t2 = AES_Td0[s2 >> 24] ^ AES_Td1[(s1 >> 16) & 0xff] ^ AES_Td2[(s0 >> 8) & 0xff] ^ AES_Td3[s3 & 0xff] ^ rk[54]; - t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[55]; - } - } - rk += key->rounds << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = key->rounds >> 1; - for (;;) { - t0 = - AES_Td0[(s0 >> 24) ] ^ - AES_Td1[(s3 >> 16) & 0xff] ^ - AES_Td2[(s2 >> 8) & 0xff] ^ - AES_Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - AES_Td0[(s1 >> 24) ] ^ - AES_Td1[(s0 >> 16) & 0xff] ^ - AES_Td2[(s3 >> 8) & 0xff] ^ - AES_Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - AES_Td0[(s2 >> 24) ] ^ - AES_Td1[(s1 >> 16) & 0xff] ^ - AES_Td2[(s0 >> 8) & 0xff] ^ - AES_Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - AES_Td0[(s3 >> 24) ] ^ - AES_Td1[(s2 >> 16) & 0xff] ^ - AES_Td2[(s1 >> 8) & 0xff] ^ - AES_Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - AES_Td0[(t0 >> 24) ] ^ - AES_Td1[(t3 >> 16) & 0xff] ^ - AES_Td2[(t2 >> 8) & 0xff] ^ - AES_Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - AES_Td0[(t1 >> 24) ] ^ - AES_Td1[(t0 >> 16) & 0xff] ^ - AES_Td2[(t3 >> 8) & 0xff] ^ - AES_Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - AES_Td0[(t2 >> 24) ] ^ - AES_Td1[(t1 >> 16) & 0xff] ^ - AES_Td2[(t0 >> 8) & 0xff] ^ - AES_Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - AES_Td0[(t3 >> 24) ] ^ - AES_Td1[(t2 >> 16) & 0xff] ^ - AES_Td2[(t1 >> 8) & 0xff] ^ - AES_Td3[(t0 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (AES_Td4[(t0 >> 24) ] & 0xff000000) ^ - (AES_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(out , s0); - s1 = - (AES_Td4[(t1 >> 24) ] & 0xff000000) ^ - (AES_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = - (AES_Td4[(t2 >> 24) ] & 0xff000000) ^ - (AES_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = - (AES_Td4[(t3 >> 24) ] & 0xff000000) ^ - (AES_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (AES_Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (AES_Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(out + 12, s3); -} - -#endif /* AES_ASM */ - -void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, - unsigned char *ivec, const int enc) -{ - - unsigned long n; - unsigned long len = length; - unsigned char tmp[AES_BLOCK_SIZE]; - - assert(in && out && key && ivec); - - if (enc) { - while (len >= AES_BLOCK_SIZE) { - for(n=0; n < AES_BLOCK_SIZE; ++n) - tmp[n] = in[n] ^ ivec[n]; - AES_encrypt(tmp, out, key); - memcpy(ivec, out, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - for(n=0; n < len; ++n) - tmp[n] = in[n] ^ ivec[n]; - for(n=len; n < AES_BLOCK_SIZE; ++n) - tmp[n] = ivec[n]; - AES_encrypt(tmp, tmp, key); - memcpy(out, tmp, AES_BLOCK_SIZE); - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } - } else { - while (len >= AES_BLOCK_SIZE) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(in, out, key); - for(n=0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= ivec[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(tmp, tmp, key); - for(n=0; n < len; ++n) - out[n] = tmp[n] ^ ivec[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } - } -} diff --git a/qemu/crypto/afsplit.c b/qemu/crypto/afsplit.c deleted file mode 100644 index 8074913cd..000000000 --- a/qemu/crypto/afsplit.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * QEMU Crypto anti forensic information splitter - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * Derived from cryptsetup package lib/luks1/af.c - * - * Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org> - * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/afsplit.h" -#include "crypto/random.h" - - -static void qcrypto_afsplit_xor(size_t blocklen, - const uint8_t *in1, - const uint8_t *in2, - uint8_t *out) -{ - size_t i; - for (i = 0; i < blocklen; i++) { - out[i] = in1[i] ^ in2[i]; - } -} - - -static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash, - size_t blocklen, - uint8_t *block, - Error **errp) -{ - size_t digestlen = qcrypto_hash_digest_len(hash); - - size_t hashcount = blocklen / digestlen; - size_t finallen = blocklen % digestlen; - uint32_t i; - - if (finallen) { - hashcount++; - } else { - finallen = digestlen; - } - - for (i = 0; i < hashcount; i++) { - uint8_t *out = NULL; - size_t outlen = 0; - uint32_t iv = cpu_to_be32(i); - struct iovec in[] = { - { .iov_base = &iv, - .iov_len = sizeof(iv) }, - { .iov_base = block + (i * digestlen), - .iov_len = (i == (hashcount - 1)) ? finallen : digestlen }, - }; - - if (qcrypto_hash_bytesv(hash, - in, - G_N_ELEMENTS(in), - &out, &outlen, - errp) < 0) { - return -1; - } - - assert(outlen == digestlen); - memcpy(block + (i * digestlen), out, - (i == (hashcount - 1)) ? finallen : digestlen); - g_free(out); - } - - return 0; -} - - -int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash, - size_t blocklen, - uint32_t stripes, - const uint8_t *in, - uint8_t *out, - Error **errp) -{ - uint8_t *block = g_new0(uint8_t, blocklen); - size_t i; - int ret = -1; - - for (i = 0; i < (stripes - 1); i++) { - if (qcrypto_random_bytes(out + (i * blocklen), blocklen, errp) < 0) { - goto cleanup; - } - - qcrypto_afsplit_xor(blocklen, - out + (i * blocklen), - block, - block); - if (qcrypto_afsplit_hash(hash, blocklen, block, - errp) < 0) { - goto cleanup; - } - } - qcrypto_afsplit_xor(blocklen, - in, - block, - out + (i * blocklen)); - ret = 0; - - cleanup: - g_free(block); - return ret; -} - - -int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash, - size_t blocklen, - uint32_t stripes, - const uint8_t *in, - uint8_t *out, - Error **errp) -{ - uint8_t *block = g_new0(uint8_t, blocklen); - size_t i; - int ret = -1; - - for (i = 0; i < (stripes - 1); i++) { - qcrypto_afsplit_xor(blocklen, - in + (i * blocklen), - block, - block); - if (qcrypto_afsplit_hash(hash, blocklen, block, - errp) < 0) { - goto cleanup; - } - } - - qcrypto_afsplit_xor(blocklen, - in + (i * blocklen), - block, - out); - - ret = 0; - - cleanup: - g_free(block); - return ret; -} diff --git a/qemu/crypto/block-luks.c b/qemu/crypto/block-luks.c deleted file mode 100644 index 439f89230..000000000 --- a/qemu/crypto/block-luks.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * QEMU Crypto block device encryption LUKS format - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" - -#include "crypto/block-luks.h" - -#include "crypto/hash.h" -#include "crypto/afsplit.h" -#include "crypto/pbkdf.h" -#include "crypto/secret.h" -#include "crypto/random.h" - -#ifdef CONFIG_UUID -#include <uuid/uuid.h> -#endif - -#include "qemu/coroutine.h" - -/* - * Reference for the LUKS format implemented here is - * - * docs/on-disk-format.pdf - * - * in 'cryptsetup' package source code - * - * This file implements the 1.2.1 specification, dated - * Oct 16, 2011. - */ - -typedef struct QCryptoBlockLUKS QCryptoBlockLUKS; -typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; -typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; - - -/* The following constants are all defined by the LUKS spec */ -#define QCRYPTO_BLOCK_LUKS_VERSION 1 - -#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 -#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 -#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 -#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 -#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 -#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 -#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 -#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 -#define QCRYPTO_BLOCK_LUKS_STRIPES 4000 -#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 - -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 - -#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL - -static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { - 'L', 'U', 'K', 'S', 0xBA, 0xBE -}; - -typedef struct QCryptoBlockLUKSNameMap QCryptoBlockLUKSNameMap; -struct QCryptoBlockLUKSNameMap { - const char *name; - int id; -}; - -typedef struct QCryptoBlockLUKSCipherSizeMap QCryptoBlockLUKSCipherSizeMap; -struct QCryptoBlockLUKSCipherSizeMap { - uint32_t key_bytes; - int id; -}; -typedef struct QCryptoBlockLUKSCipherNameMap QCryptoBlockLUKSCipherNameMap; -struct QCryptoBlockLUKSCipherNameMap { - const char *name; - const QCryptoBlockLUKSCipherSizeMap *sizes; -}; - - -static const QCryptoBlockLUKSCipherSizeMap -qcrypto_block_luks_cipher_size_map_aes[] = { - { 16, QCRYPTO_CIPHER_ALG_AES_128 }, - { 24, QCRYPTO_CIPHER_ALG_AES_192 }, - { 32, QCRYPTO_CIPHER_ALG_AES_256 }, - { 0, 0 }, -}; - -static const QCryptoBlockLUKSCipherSizeMap -qcrypto_block_luks_cipher_size_map_cast5[] = { - { 16, QCRYPTO_CIPHER_ALG_CAST5_128 }, - { 0, 0 }, -}; - -static const QCryptoBlockLUKSCipherSizeMap -qcrypto_block_luks_cipher_size_map_serpent[] = { - { 16, QCRYPTO_CIPHER_ALG_SERPENT_128 }, - { 24, QCRYPTO_CIPHER_ALG_SERPENT_192 }, - { 32, QCRYPTO_CIPHER_ALG_SERPENT_256 }, - { 0, 0 }, -}; - -static const QCryptoBlockLUKSCipherSizeMap -qcrypto_block_luks_cipher_size_map_twofish[] = { - { 16, QCRYPTO_CIPHER_ALG_TWOFISH_128 }, - { 24, QCRYPTO_CIPHER_ALG_TWOFISH_192 }, - { 32, QCRYPTO_CIPHER_ALG_TWOFISH_256 }, - { 0, 0 }, -}; - -static const QCryptoBlockLUKSCipherNameMap -qcrypto_block_luks_cipher_name_map[] = { - { "aes", qcrypto_block_luks_cipher_size_map_aes }, - { "cast5", qcrypto_block_luks_cipher_size_map_cast5 }, - { "serpent", qcrypto_block_luks_cipher_size_map_serpent }, - { "twofish", qcrypto_block_luks_cipher_size_map_twofish }, -}; - - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSKeySlot { - /* state of keyslot, enabled/disable */ - uint32_t active; - /* iterations for PBKDF2 */ - uint32_t iterations; - /* salt for PBKDF2 */ - uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - /* start sector of key material */ - uint32_t key_offset; - /* number of anti-forensic stripes */ - uint32_t stripes; -} QEMU_PACKED; - -QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48); - - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSHeader { - /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ - char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; - - /* LUKS version, currently 1 */ - uint16_t version; - - /* cipher name specification (aes, etc) */ - char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; - - /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ - char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; - - /* hash specification (sha256, etc) */ - char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; - - /* start offset of the volume data (in 512 byte sectors) */ - uint32_t payload_offset; - - /* Number of key bytes */ - uint32_t key_bytes; - - /* master key checksum after PBKDF2 */ - uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; - - /* salt for master key PBKDF2 */ - uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - - /* iterations for master key PBKDF2 */ - uint32_t master_key_iterations; - - /* UUID of the partition in standard ASCII representation */ - uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; - - /* key slots */ - QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; -} QEMU_PACKED; - -QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592); - - -struct QCryptoBlockLUKS { - QCryptoBlockLUKSHeader header; -}; - - -static int qcrypto_block_luks_cipher_name_lookup(const char *name, - QCryptoCipherMode mode, - uint32_t key_bytes, - Error **errp) -{ - const QCryptoBlockLUKSCipherNameMap *map = - qcrypto_block_luks_cipher_name_map; - size_t maplen = G_N_ELEMENTS(qcrypto_block_luks_cipher_name_map); - size_t i, j; - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - key_bytes /= 2; - } - - for (i = 0; i < maplen; i++) { - if (!g_str_equal(map[i].name, name)) { - continue; - } - for (j = 0; j < map[i].sizes[j].key_bytes; j++) { - if (map[i].sizes[j].key_bytes == key_bytes) { - return map[i].sizes[j].id; - } - } - } - - error_setg(errp, "Algorithm %s with key size %d bytes not supported", - name, key_bytes); - return 0; -} - -static const char * -qcrypto_block_luks_cipher_alg_lookup(QCryptoCipherAlgorithm alg, - Error **errp) -{ - const QCryptoBlockLUKSCipherNameMap *map = - qcrypto_block_luks_cipher_name_map; - size_t maplen = G_N_ELEMENTS(qcrypto_block_luks_cipher_name_map); - size_t i, j; - for (i = 0; i < maplen; i++) { - for (j = 0; j < map[i].sizes[j].key_bytes; j++) { - if (map[i].sizes[j].id == alg) { - return map[i].name; - } - } - } - - error_setg(errp, "Algorithm '%s' not supported", - QCryptoCipherAlgorithm_lookup[alg]); - return NULL; -} - -/* XXX replace with qapi_enum_parse() in future, when we can - * make that function emit a more friendly error message */ -static int qcrypto_block_luks_name_lookup(const char *name, - const char *const *map, - size_t maplen, - const char *type, - Error **errp) -{ - size_t i; - for (i = 0; i < maplen; i++) { - if (g_str_equal(map[i], name)) { - return i; - } - } - - error_setg(errp, "%s %s not supported", type, name); - return 0; -} - -#define qcrypto_block_luks_cipher_mode_lookup(name, errp) \ - qcrypto_block_luks_name_lookup(name, \ - QCryptoCipherMode_lookup, \ - QCRYPTO_CIPHER_MODE__MAX, \ - "Cipher mode", \ - errp) - -#define qcrypto_block_luks_hash_name_lookup(name, errp) \ - qcrypto_block_luks_name_lookup(name, \ - QCryptoHashAlgorithm_lookup, \ - QCRYPTO_HASH_ALG__MAX, \ - "Hash algorithm", \ - errp) - -#define qcrypto_block_luks_ivgen_name_lookup(name, errp) \ - qcrypto_block_luks_name_lookup(name, \ - QCryptoIVGenAlgorithm_lookup, \ - QCRYPTO_IVGEN_ALG__MAX, \ - "IV generator", \ - errp) - - -static bool -qcrypto_block_luks_has_format(const uint8_t *buf, - size_t buf_size) -{ - const QCryptoBlockLUKSHeader *luks_header = (const void *)buf; - - if (buf_size >= offsetof(QCryptoBlockLUKSHeader, cipher_name) && - memcmp(luks_header->magic, qcrypto_block_luks_magic, - QCRYPTO_BLOCK_LUKS_MAGIC_LEN) == 0 && - be16_to_cpu(luks_header->version) == QCRYPTO_BLOCK_LUKS_VERSION) { - return true; - } else { - return false; - } -} - - -/** - * Deal with a quirk of dm-crypt usage of ESSIV. - * - * When calculating ESSIV IVs, the cipher length used by ESSIV - * may be different from the cipher length used for the block - * encryption, becauses dm-crypt uses the hash digest length - * as the key size. ie, if you have AES 128 as the block cipher - * and SHA 256 as ESSIV hash, then ESSIV will use AES 256 as - * the cipher since that gets a key length matching the digest - * size, not AES 128 with truncated digest as might be imagined - */ -static QCryptoCipherAlgorithm -qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher, - QCryptoHashAlgorithm hash, - Error **errp) -{ - size_t digestlen = qcrypto_hash_digest_len(hash); - size_t keylen = qcrypto_cipher_get_key_len(cipher); - if (digestlen == keylen) { - return cipher; - } - - switch (cipher) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_128)) { - return QCRYPTO_CIPHER_ALG_AES_128; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_192)) { - return QCRYPTO_CIPHER_ALG_AES_192; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_AES_256)) { - return QCRYPTO_CIPHER_ALG_AES_256; - } else { - error_setg(errp, "No AES cipher with key size %zu available", - digestlen); - return 0; - } - break; - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_128)) { - return QCRYPTO_CIPHER_ALG_SERPENT_128; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_192)) { - return QCRYPTO_CIPHER_ALG_SERPENT_192; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_SERPENT_256)) { - return QCRYPTO_CIPHER_ALG_SERPENT_256; - } else { - error_setg(errp, "No Serpent cipher with key size %zu available", - digestlen); - return 0; - } - break; - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_128)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_128; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_192)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_192; - } else if (digestlen == qcrypto_cipher_get_key_len( - QCRYPTO_CIPHER_ALG_TWOFISH_256)) { - return QCRYPTO_CIPHER_ALG_TWOFISH_256; - } else { - error_setg(errp, "No Twofish cipher with key size %zu available", - digestlen); - return 0; - } - break; - default: - error_setg(errp, "Cipher %s not supported with essiv", - QCryptoCipherAlgorithm_lookup[cipher]); - return 0; - } -} - -/* - * Given a key slot, and user password, this will attempt to unlock - * the master encryption key from the key slot. - * - * Returns: - * 0 if the key slot is disabled, or key could not be decrypted - * with the provided password - * 1 if the key slot is enabled, and key decrypted successfully - * with the provided password - * -1 if a fatal error occurred loading the key - */ -static int -qcrypto_block_luks_load_key(QCryptoBlock *block, - QCryptoBlockLUKSKeySlot *slot, - const char *password, - QCryptoCipherAlgorithm cipheralg, - QCryptoCipherMode ciphermode, - QCryptoHashAlgorithm hash, - QCryptoIVGenAlgorithm ivalg, - QCryptoCipherAlgorithm ivcipheralg, - QCryptoHashAlgorithm ivhash, - uint8_t *masterkey, - size_t masterkeylen, - QCryptoBlockReadFunc readfunc, - void *opaque, - Error **errp) -{ - QCryptoBlockLUKS *luks = block->opaque; - uint8_t *splitkey; - size_t splitkeylen; - uint8_t *possiblekey; - int ret = -1; - ssize_t rv; - QCryptoCipher *cipher = NULL; - uint8_t keydigest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; - QCryptoIVGen *ivgen = NULL; - size_t niv; - - if (slot->active != QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED) { - return 0; - } - - splitkeylen = masterkeylen * slot->stripes; - splitkey = g_new0(uint8_t, splitkeylen); - possiblekey = g_new0(uint8_t, masterkeylen); - - /* - * The user password is used to generate a (possible) - * decryption key. This may or may not successfully - * decrypt the master key - we just blindly assume - * the key is correct and validate the results of - * decryption later. - */ - if (qcrypto_pbkdf2(hash, - (const uint8_t *)password, strlen(password), - slot->salt, QCRYPTO_BLOCK_LUKS_SALT_LEN, - slot->iterations, - possiblekey, masterkeylen, - errp) < 0) { - goto cleanup; - } - - /* - * We need to read the master key material from the - * LUKS key material header. What we're reading is - * not the raw master key, but rather the data after - * it has been passed through AFSplit and the result - * then encrypted. - */ - rv = readfunc(block, - slot->key_offset * QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - splitkey, splitkeylen, - errp, - opaque); - if (rv < 0) { - goto cleanup; - } - - - /* Setup the cipher/ivgen that we'll use to try to decrypt - * the split master key material */ - cipher = qcrypto_cipher_new(cipheralg, ciphermode, - possiblekey, masterkeylen, - errp); - if (!cipher) { - goto cleanup; - } - - niv = qcrypto_cipher_get_iv_len(cipheralg, - ciphermode); - ivgen = qcrypto_ivgen_new(ivalg, - ivcipheralg, - ivhash, - possiblekey, masterkeylen, - errp); - if (!ivgen) { - goto cleanup; - } - - - /* - * The master key needs to be decrypted in the same - * way that the block device payload will be decrypted - * later. In particular we'll be using the IV generator - * to reset the encryption cipher every time the master - * key crosses a sector boundary. - */ - if (qcrypto_block_decrypt_helper(cipher, - niv, - ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { - goto cleanup; - } - - /* - * Now we've decrypted the split master key, join - * it back together to get the actual master key. - */ - if (qcrypto_afsplit_decode(hash, - masterkeylen, - slot->stripes, - splitkey, - masterkey, - errp) < 0) { - goto cleanup; - } - - - /* - * We still don't know that the masterkey we got is valid, - * because we just blindly assumed the user's password - * was correct. This is where we now verify it. We are - * creating a hash of the master key using PBKDF and - * then comparing that to the hash stored in the key slot - * header - */ - if (qcrypto_pbkdf2(hash, - masterkey, masterkeylen, - luks->header.master_key_salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - luks->header.master_key_iterations, - keydigest, G_N_ELEMENTS(keydigest), - errp) < 0) { - goto cleanup; - } - - if (memcmp(keydigest, luks->header.master_key_digest, - QCRYPTO_BLOCK_LUKS_DIGEST_LEN) == 0) { - /* Success, we got the right master key */ - ret = 1; - goto cleanup; - } - - /* Fail, user's password was not valid for this key slot, - * tell caller to try another slot */ - ret = 0; - - cleanup: - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); - g_free(splitkey); - g_free(possiblekey); - return ret; -} - - -/* - * Given a user password, this will iterate over all key - * slots and try to unlock each active key slot using the - * password until it successfully obtains a master key. - * - * Returns 0 if a key was loaded, -1 if no keys could be loaded - */ -static int -qcrypto_block_luks_find_key(QCryptoBlock *block, - const char *password, - QCryptoCipherAlgorithm cipheralg, - QCryptoCipherMode ciphermode, - QCryptoHashAlgorithm hash, - QCryptoIVGenAlgorithm ivalg, - QCryptoCipherAlgorithm ivcipheralg, - QCryptoHashAlgorithm ivhash, - uint8_t **masterkey, - size_t *masterkeylen, - QCryptoBlockReadFunc readfunc, - void *opaque, - Error **errp) -{ - QCryptoBlockLUKS *luks = block->opaque; - size_t i; - int rv; - - *masterkey = g_new0(uint8_t, luks->header.key_bytes); - *masterkeylen = luks->header.key_bytes; - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - rv = qcrypto_block_luks_load_key(block, - &luks->header.key_slots[i], - password, - cipheralg, - ciphermode, - hash, - ivalg, - ivcipheralg, - ivhash, - *masterkey, - *masterkeylen, - readfunc, - opaque, - errp); - if (rv < 0) { - goto error; - } - if (rv == 1) { - return 0; - } - } - - error_setg(errp, "Invalid password, cannot unlock any keyslot"); - - error: - g_free(*masterkey); - *masterkey = NULL; - *masterkeylen = 0; - return -1; -} - - -static int -qcrypto_block_luks_open(QCryptoBlock *block, - QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, - Error **errp) -{ - QCryptoBlockLUKS *luks; - Error *local_err = NULL; - int ret = 0; - size_t i; - ssize_t rv; - uint8_t *masterkey = NULL; - size_t masterkeylen; - char *ivgen_name, *ivhash_name; - QCryptoCipherMode ciphermode; - QCryptoCipherAlgorithm cipheralg; - QCryptoIVGenAlgorithm ivalg; - QCryptoCipherAlgorithm ivcipheralg; - QCryptoHashAlgorithm hash; - QCryptoHashAlgorithm ivhash; - char *password = NULL; - - if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { - if (!options->u.luks.key_secret) { - error_setg(errp, "Parameter 'key-secret' is required for cipher"); - return -1; - } - password = qcrypto_secret_lookup_as_utf8( - options->u.luks.key_secret, errp); - if (!password) { - return -1; - } - } - - luks = g_new0(QCryptoBlockLUKS, 1); - block->opaque = luks; - - /* Read the entire LUKS header, minus the key material from - * the underlying device */ - rv = readfunc(block, 0, - (uint8_t *)&luks->header, - sizeof(luks->header), - errp, - opaque); - if (rv < 0) { - ret = rv; - goto fail; - } - - /* The header is always stored in big-endian format, so - * convert everything to native */ - be16_to_cpus(&luks->header.version); - be32_to_cpus(&luks->header.payload_offset); - be32_to_cpus(&luks->header.key_bytes); - be32_to_cpus(&luks->header.master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - be32_to_cpus(&luks->header.key_slots[i].active); - be32_to_cpus(&luks->header.key_slots[i].iterations); - be32_to_cpus(&luks->header.key_slots[i].key_offset); - be32_to_cpus(&luks->header.key_slots[i].stripes); - } - - if (memcmp(luks->header.magic, qcrypto_block_luks_magic, - QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) { - error_setg(errp, "Volume is not in LUKS format"); - ret = -EINVAL; - goto fail; - } - if (luks->header.version != QCRYPTO_BLOCK_LUKS_VERSION) { - error_setg(errp, "LUKS version %" PRIu32 " is not supported", - luks->header.version); - ret = -ENOTSUP; - goto fail; - } - - /* - * The cipher_mode header contains a string that we have - * to further parse, of the format - * - * <cipher-mode>-<iv-generator>[:<iv-hash>] - * - * eg cbc-essiv:sha256, cbc-plain64 - */ - ivgen_name = strchr(luks->header.cipher_mode, '-'); - if (!ivgen_name) { - ret = -EINVAL; - error_setg(errp, "Unexpected cipher mode string format %s", - luks->header.cipher_mode); - goto fail; - } - *ivgen_name = '\0'; - ivgen_name++; - - ivhash_name = strchr(ivgen_name, ':'); - if (!ivhash_name) { - ivhash = 0; - } else { - *ivhash_name = '\0'; - ivhash_name++; - - ivhash = qcrypto_block_luks_hash_name_lookup(ivhash_name, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - } - - ciphermode = qcrypto_block_luks_cipher_mode_lookup(luks->header.cipher_mode, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - - cipheralg = qcrypto_block_luks_cipher_name_lookup(luks->header.cipher_name, - ciphermode, - luks->header.key_bytes, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - - hash = qcrypto_block_luks_hash_name_lookup(luks->header.hash_spec, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - - ivalg = qcrypto_block_luks_ivgen_name_lookup(ivgen_name, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - - if (ivalg == QCRYPTO_IVGEN_ALG_ESSIV) { - ivcipheralg = qcrypto_block_luks_essiv_cipher(cipheralg, - ivhash, - &local_err); - if (local_err) { - ret = -ENOTSUP; - error_propagate(errp, local_err); - goto fail; - } - } else { - ivcipheralg = cipheralg; - } - - if (!(flags & QCRYPTO_BLOCK_OPEN_NO_IO)) { - /* Try to find which key slot our password is valid for - * and unlock the master key from that slot. - */ - if (qcrypto_block_luks_find_key(block, - password, - cipheralg, ciphermode, - hash, - ivalg, - ivcipheralg, - ivhash, - &masterkey, &masterkeylen, - readfunc, opaque, - errp) < 0) { - ret = -EACCES; - goto fail; - } - - /* We have a valid master key now, so can setup the - * block device payload decryption objects - */ - block->kdfhash = hash; - block->niv = qcrypto_cipher_get_iv_len(cipheralg, - ciphermode); - block->ivgen = qcrypto_ivgen_new(ivalg, - ivcipheralg, - ivhash, - masterkey, masterkeylen, - errp); - if (!block->ivgen) { - ret = -ENOTSUP; - goto fail; - } - - block->cipher = qcrypto_cipher_new(cipheralg, - ciphermode, - masterkey, masterkeylen, - errp); - if (!block->cipher) { - ret = -ENOTSUP; - goto fail; - } - } - - block->payload_offset = luks->header.payload_offset * - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; - - g_free(masterkey); - g_free(password); - - return 0; - - fail: - g_free(masterkey); - qcrypto_cipher_free(block->cipher); - qcrypto_ivgen_free(block->ivgen); - g_free(luks); - g_free(password); - return ret; -} - - -static int -qcrypto_block_luks_uuid_gen(uint8_t *uuidstr, Error **errp) -{ -#ifdef CONFIG_UUID - uuid_t uuid; - uuid_generate(uuid); - uuid_unparse(uuid, (char *)uuidstr); - return 0; -#else - error_setg(errp, "Unable to generate uuids on this platform"); - return -1; -#endif -} - -static int -qcrypto_block_luks_create(QCryptoBlock *block, - QCryptoBlockCreateOptions *options, - QCryptoBlockInitFunc initfunc, - QCryptoBlockWriteFunc writefunc, - void *opaque, - Error **errp) -{ - QCryptoBlockLUKS *luks; - QCryptoBlockCreateOptionsLUKS luks_opts; - Error *local_err = NULL; - uint8_t *masterkey = NULL; - uint8_t *slotkey = NULL; - uint8_t *splitkey = NULL; - size_t splitkeylen = 0; - size_t i; - QCryptoCipher *cipher = NULL; - QCryptoIVGen *ivgen = NULL; - char *password; - const char *cipher_alg; - const char *cipher_mode; - const char *ivgen_alg; - const char *ivgen_hash_alg = NULL; - const char *hash_alg; - char *cipher_mode_spec = NULL; - QCryptoCipherAlgorithm ivcipheralg = 0; - - memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts)); - if (!luks_opts.has_cipher_alg) { - luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256; - } - if (!luks_opts.has_cipher_mode) { - luks_opts.cipher_mode = QCRYPTO_CIPHER_MODE_XTS; - } - if (!luks_opts.has_ivgen_alg) { - luks_opts.ivgen_alg = QCRYPTO_IVGEN_ALG_PLAIN64; - } - if (!luks_opts.has_hash_alg) { - luks_opts.hash_alg = QCRYPTO_HASH_ALG_SHA256; - } - - if (!options->u.luks.key_secret) { - error_setg(errp, "Parameter 'key-secret' is required for cipher"); - return -1; - } - password = qcrypto_secret_lookup_as_utf8(luks_opts.key_secret, errp); - if (!password) { - return -1; - } - - luks = g_new0(QCryptoBlockLUKS, 1); - block->opaque = luks; - - memcpy(luks->header.magic, qcrypto_block_luks_magic, - QCRYPTO_BLOCK_LUKS_MAGIC_LEN); - - /* We populate the header in native endianness initially and - * then convert everything to big endian just before writing - * it out to disk - */ - luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION; - if (qcrypto_block_luks_uuid_gen(luks->header.uuid, - errp) < 0) { - goto error; - } - - cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg, - errp); - if (!cipher_alg) { - goto error; - } - - cipher_mode = QCryptoCipherMode_lookup[luks_opts.cipher_mode]; - ivgen_alg = QCryptoIVGenAlgorithm_lookup[luks_opts.ivgen_alg]; - if (luks_opts.has_ivgen_hash_alg) { - ivgen_hash_alg = QCryptoHashAlgorithm_lookup[luks_opts.ivgen_hash_alg]; - cipher_mode_spec = g_strdup_printf("%s-%s:%s", cipher_mode, ivgen_alg, - ivgen_hash_alg); - } else { - cipher_mode_spec = g_strdup_printf("%s-%s", cipher_mode, ivgen_alg); - } - hash_alg = QCryptoHashAlgorithm_lookup[luks_opts.hash_alg]; - - - if (strlen(cipher_alg) >= QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN) { - error_setg(errp, "Cipher name '%s' is too long for LUKS header", - cipher_alg); - goto error; - } - if (strlen(cipher_mode_spec) >= QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN) { - error_setg(errp, "Cipher mode '%s' is too long for LUKS header", - cipher_mode_spec); - goto error; - } - if (strlen(hash_alg) >= QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN) { - error_setg(errp, "Hash name '%s' is too long for LUKS header", - hash_alg); - goto error; - } - - if (luks_opts.ivgen_alg == QCRYPTO_IVGEN_ALG_ESSIV) { - ivcipheralg = qcrypto_block_luks_essiv_cipher(luks_opts.cipher_alg, - luks_opts.ivgen_hash_alg, - &local_err); - if (local_err) { - error_propagate(errp, local_err); - goto error; - } - } else { - ivcipheralg = luks_opts.cipher_alg; - } - - strcpy(luks->header.cipher_name, cipher_alg); - strcpy(luks->header.cipher_mode, cipher_mode_spec); - strcpy(luks->header.hash_spec, hash_alg); - - luks->header.key_bytes = qcrypto_cipher_get_key_len(luks_opts.cipher_alg); - if (luks_opts.cipher_mode == QCRYPTO_CIPHER_MODE_XTS) { - luks->header.key_bytes *= 2; - } - - /* Generate the salt used for hashing the master key - * with PBKDF later - */ - if (qcrypto_random_bytes(luks->header.master_key_salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - errp) < 0) { - goto error; - } - - /* Generate random master key */ - masterkey = g_new0(uint8_t, luks->header.key_bytes); - if (qcrypto_random_bytes(masterkey, - luks->header.key_bytes, errp) < 0) { - goto error; - } - - - /* Setup the block device payload encryption objects */ - block->cipher = qcrypto_cipher_new(luks_opts.cipher_alg, - luks_opts.cipher_mode, - masterkey, luks->header.key_bytes, - errp); - if (!block->cipher) { - goto error; - } - - block->kdfhash = luks_opts.hash_alg; - block->niv = qcrypto_cipher_get_iv_len(luks_opts.cipher_alg, - luks_opts.cipher_mode); - block->ivgen = qcrypto_ivgen_new(luks_opts.ivgen_alg, - ivcipheralg, - luks_opts.ivgen_hash_alg, - masterkey, luks->header.key_bytes, - errp); - - if (!block->ivgen) { - goto error; - } - - - /* Determine how many iterations we need to hash the master - * key, in order to have 1 second of compute time used - */ - luks->header.master_key_iterations = - qcrypto_pbkdf2_count_iters(luks_opts.hash_alg, - masterkey, luks->header.key_bytes, - luks->header.master_key_salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - &local_err); - if (local_err) { - error_propagate(errp, local_err); - goto error; - } - - /* Why /= 8 ? That matches cryptsetup, but there's no - * explanation why they chose /= 8... Probably so that - * if all 8 keyslots are active we only spend 1 second - * in total time to check all keys */ - luks->header.master_key_iterations /= 8; - luks->header.master_key_iterations = MAX( - luks->header.master_key_iterations, - QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS); - - - /* Hash the master key, saving the result in the LUKS - * header. This hash is used when opening the encrypted - * device to verify that the user password unlocked a - * valid master key - */ - if (qcrypto_pbkdf2(luks_opts.hash_alg, - masterkey, luks->header.key_bytes, - luks->header.master_key_salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - luks->header.master_key_iterations, - luks->header.master_key_digest, - QCRYPTO_BLOCK_LUKS_DIGEST_LEN, - errp) < 0) { - goto error; - } - - - /* Although LUKS has multiple key slots, we're just going - * to use the first key slot */ - splitkeylen = luks->header.key_bytes * QCRYPTO_BLOCK_LUKS_STRIPES; - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - luks->header.key_slots[i].active = i == 0 ? - QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED : - QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED; - luks->header.key_slots[i].stripes = QCRYPTO_BLOCK_LUKS_STRIPES; - - /* This calculation doesn't match that shown in the spec, - * but instead follows the cryptsetup implementation. - */ - luks->header.key_slots[i].key_offset = - (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) + - (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), - (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) * i); - } - - if (qcrypto_random_bytes(luks->header.key_slots[0].salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - errp) < 0) { - goto error; - } - - /* Again we determine how many iterations are required to - * hash the user password while consuming 1 second of compute - * time */ - luks->header.key_slots[0].iterations = - qcrypto_pbkdf2_count_iters(luks_opts.hash_alg, - (uint8_t *)password, strlen(password), - luks->header.key_slots[0].salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - &local_err); - if (local_err) { - error_propagate(errp, local_err); - goto error; - } - /* Why /= 2 ? That matches cryptsetup, but there's no - * explanation why they chose /= 2... */ - luks->header.key_slots[0].iterations /= 2; - luks->header.key_slots[0].iterations = MAX( - luks->header.key_slots[0].iterations, - QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS); - - - /* Generate a key that we'll use to encrypt the master - * key, from the user's password - */ - slotkey = g_new0(uint8_t, luks->header.key_bytes); - if (qcrypto_pbkdf2(luks_opts.hash_alg, - (uint8_t *)password, strlen(password), - luks->header.key_slots[0].salt, - QCRYPTO_BLOCK_LUKS_SALT_LEN, - luks->header.key_slots[0].iterations, - slotkey, luks->header.key_bytes, - errp) < 0) { - goto error; - } - - - /* Setup the encryption objects needed to encrypt the - * master key material - */ - cipher = qcrypto_cipher_new(luks_opts.cipher_alg, - luks_opts.cipher_mode, - slotkey, luks->header.key_bytes, - errp); - if (!cipher) { - goto error; - } - - ivgen = qcrypto_ivgen_new(luks_opts.ivgen_alg, - ivcipheralg, - luks_opts.ivgen_hash_alg, - slotkey, luks->header.key_bytes, - errp); - if (!ivgen) { - goto error; - } - - /* Before storing the master key, we need to vastly - * increase its size, as protection against forensic - * disk data recovery */ - splitkey = g_new0(uint8_t, splitkeylen); - - if (qcrypto_afsplit_encode(luks_opts.hash_alg, - luks->header.key_bytes, - luks->header.key_slots[0].stripes, - masterkey, - splitkey, - errp) < 0) { - goto error; - } - - /* Now we encrypt the split master key with the key generated - * from the user's password, before storing it */ - if (qcrypto_block_encrypt_helper(cipher, block->niv, ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { - goto error; - } - - - /* The total size of the LUKS headers is the partition header + key - * slot headers, rounded up to the nearest sector, combined with - * the size of each master key material region, also rounded up - * to the nearest sector */ - luks->header.payload_offset = - (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE) + - (ROUND_UP(((splitkeylen + (QCRYPTO_BLOCK_LUKS_SECTOR_SIZE - 1)) / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE), - (QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET / - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) * - QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS); - - block->payload_offset = luks->header.payload_offset * - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE; - - /* Reserve header space to match payload offset */ - initfunc(block, block->payload_offset, &local_err, opaque); - if (local_err) { - error_propagate(errp, local_err); - goto error; - } - - /* Everything on disk uses Big Endian, so flip header fields - * before writing them */ - cpu_to_be16s(&luks->header.version); - cpu_to_be32s(&luks->header.payload_offset); - cpu_to_be32s(&luks->header.key_bytes); - cpu_to_be32s(&luks->header.master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - cpu_to_be32s(&luks->header.key_slots[i].active); - cpu_to_be32s(&luks->header.key_slots[i].iterations); - cpu_to_be32s(&luks->header.key_slots[i].key_offset); - cpu_to_be32s(&luks->header.key_slots[i].stripes); - } - - - /* Write out the partition header and key slot headers */ - writefunc(block, 0, - (const uint8_t *)&luks->header, - sizeof(luks->header), - &local_err, - opaque); - - /* Delay checking local_err until we've byte-swapped */ - - /* Byte swap the header back to native, in case we need - * to read it again later */ - be16_to_cpus(&luks->header.version); - be32_to_cpus(&luks->header.payload_offset); - be32_to_cpus(&luks->header.key_bytes); - be32_to_cpus(&luks->header.master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - be32_to_cpus(&luks->header.key_slots[i].active); - be32_to_cpus(&luks->header.key_slots[i].iterations); - be32_to_cpus(&luks->header.key_slots[i].key_offset); - be32_to_cpus(&luks->header.key_slots[i].stripes); - } - - if (local_err) { - error_propagate(errp, local_err); - goto error; - } - - /* Write out the master key material, starting at the - * sector immediately following the partition header. */ - if (writefunc(block, - luks->header.key_slots[0].key_offset * - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - splitkey, splitkeylen, - errp, - opaque) != splitkeylen) { - goto error; - } - - memset(masterkey, 0, luks->header.key_bytes); - g_free(masterkey); - memset(slotkey, 0, luks->header.key_bytes); - g_free(slotkey); - g_free(splitkey); - g_free(password); - g_free(cipher_mode_spec); - - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); - - return 0; - - error: - if (masterkey) { - memset(masterkey, 0, luks->header.key_bytes); - } - g_free(masterkey); - if (slotkey) { - memset(slotkey, 0, luks->header.key_bytes); - } - g_free(slotkey); - g_free(splitkey); - g_free(password); - g_free(cipher_mode_spec); - - qcrypto_ivgen_free(ivgen); - qcrypto_cipher_free(cipher); - - g_free(luks); - return -1; -} - - -static void qcrypto_block_luks_cleanup(QCryptoBlock *block) -{ - g_free(block->opaque); -} - - -static int -qcrypto_block_luks_decrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - startsector, buf, len, errp); -} - - -static int -qcrypto_block_luks_encrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - startsector, buf, len, errp); -} - - -const QCryptoBlockDriver qcrypto_block_driver_luks = { - .open = qcrypto_block_luks_open, - .create = qcrypto_block_luks_create, - .cleanup = qcrypto_block_luks_cleanup, - .decrypt = qcrypto_block_luks_decrypt, - .encrypt = qcrypto_block_luks_encrypt, - .has_format = qcrypto_block_luks_has_format, -}; diff --git a/qemu/crypto/block-luks.h b/qemu/crypto/block-luks.h deleted file mode 100644 index 0934138aa..000000000 --- a/qemu/crypto/block-luks.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QEMU Crypto block device encryption LUKS format - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef QCRYPTO_BLOCK_LUKS_H__ -#define QCRYPTO_BLOCK_LUKS_H__ - -#include "crypto/blockpriv.h" - -extern const QCryptoBlockDriver qcrypto_block_driver_luks; - -#endif /* QCRYPTO_BLOCK_LUKS_H__ */ diff --git a/qemu/crypto/block-qcow.c b/qemu/crypto/block-qcow.c deleted file mode 100644 index be88c6f0e..000000000 --- a/qemu/crypto/block-qcow.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * QEMU Crypto block device encryption QCow/QCow2 AES-CBC format - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -/* - * Note that the block encryption implemented in this file is broken - * by design. This exists only to allow data to be liberated from - * existing qcow[2] images and should not be used in any new areas. - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" - -#include "crypto/block-qcow.h" -#include "crypto/secret.h" - -#define QCRYPTO_BLOCK_QCOW_SECTOR_SIZE 512 - - -static bool -qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED, - size_t buf_size G_GNUC_UNUSED) -{ - return false; -} - - -static int -qcrypto_block_qcow_init(QCryptoBlock *block, - const char *keysecret, - Error **errp) -{ - char *password; - int ret; - uint8_t keybuf[16]; - int len; - - memset(keybuf, 0, 16); - - password = qcrypto_secret_lookup_as_utf8(keysecret, errp); - if (!password) { - return -1; - } - - len = strlen(password); - memcpy(keybuf, password, MIN(len, sizeof(keybuf))); - g_free(password); - - block->niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC); - block->ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_PLAIN64, - 0, 0, NULL, 0, errp); - if (!block->ivgen) { - ret = -ENOTSUP; - goto fail; - } - - block->cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC, - keybuf, G_N_ELEMENTS(keybuf), - errp); - if (!block->cipher) { - ret = -ENOTSUP; - goto fail; - } - - block->payload_offset = 0; - - return 0; - - fail: - qcrypto_cipher_free(block->cipher); - qcrypto_ivgen_free(block->ivgen); - return ret; -} - - -static int -qcrypto_block_qcow_open(QCryptoBlock *block, - QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED, - unsigned int flags, - Error **errp) -{ - if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) { - return 0; - } else { - if (!options->u.qcow.key_secret) { - error_setg(errp, - "Parameter 'key-secret' is required for cipher"); - return -1; - } - return qcrypto_block_qcow_init(block, - options->u.qcow.key_secret, errp); - } -} - - -static int -qcrypto_block_qcow_create(QCryptoBlock *block, - QCryptoBlockCreateOptions *options, - QCryptoBlockInitFunc initfunc G_GNUC_UNUSED, - QCryptoBlockWriteFunc writefunc G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED, - Error **errp) -{ - if (!options->u.qcow.key_secret) { - error_setg(errp, "Parameter 'key-secret' is required for cipher"); - return -1; - } - /* QCow2 has no special header, since everything is hardwired */ - return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp); -} - - -static void -qcrypto_block_qcow_cleanup(QCryptoBlock *block) -{ -} - - -static int -qcrypto_block_qcow_decrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - startsector, buf, len, errp); -} - - -static int -qcrypto_block_qcow_encrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, - QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, - startsector, buf, len, errp); -} - - -const QCryptoBlockDriver qcrypto_block_driver_qcow = { - .open = qcrypto_block_qcow_open, - .create = qcrypto_block_qcow_create, - .cleanup = qcrypto_block_qcow_cleanup, - .decrypt = qcrypto_block_qcow_decrypt, - .encrypt = qcrypto_block_qcow_encrypt, - .has_format = qcrypto_block_qcow_has_format, -}; diff --git a/qemu/crypto/block-qcow.h b/qemu/crypto/block-qcow.h deleted file mode 100644 index 569f83610..000000000 --- a/qemu/crypto/block-qcow.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QEMU Crypto block device encryption QCow/QCow2 AES-CBC format - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef QCRYPTO_BLOCK_QCOW_H__ -#define QCRYPTO_BLOCK_QCOW_H__ - -#include "crypto/blockpriv.h" - -extern const QCryptoBlockDriver qcrypto_block_driver_qcow; - -#endif /* QCRYPTO_BLOCK_QCOW_H__ */ diff --git a/qemu/crypto/block.c b/qemu/crypto/block.c deleted file mode 100644 index da60eba85..000000000 --- a/qemu/crypto/block.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * QEMU Crypto block device encryption - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/blockpriv.h" -#include "crypto/block-qcow.h" -#include "crypto/block-luks.h" - -static const QCryptoBlockDriver *qcrypto_block_drivers[] = { - [Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow, - [Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks, -}; - - -bool qcrypto_block_has_format(QCryptoBlockFormat format, - const uint8_t *buf, - size_t len) -{ - const QCryptoBlockDriver *driver; - - if (format >= G_N_ELEMENTS(qcrypto_block_drivers) || - !qcrypto_block_drivers[format]) { - return false; - } - - driver = qcrypto_block_drivers[format]; - - return driver->has_format(buf, len); -} - - -QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, - Error **errp) -{ - QCryptoBlock *block = g_new0(QCryptoBlock, 1); - - block->format = options->format; - - if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || - !qcrypto_block_drivers[options->format]) { - error_setg(errp, "Unsupported block driver %d", options->format); - g_free(block); - return NULL; - } - - block->driver = qcrypto_block_drivers[options->format]; - - if (block->driver->open(block, options, - readfunc, opaque, flags, errp) < 0) { - g_free(block); - return NULL; - } - - return block; -} - - -QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, - QCryptoBlockInitFunc initfunc, - QCryptoBlockWriteFunc writefunc, - void *opaque, - Error **errp) -{ - QCryptoBlock *block = g_new0(QCryptoBlock, 1); - - block->format = options->format; - - if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || - !qcrypto_block_drivers[options->format]) { - error_setg(errp, "Unsupported block driver %d", options->format); - g_free(block); - return NULL; - } - - block->driver = qcrypto_block_drivers[options->format]; - - if (block->driver->create(block, options, initfunc, - writefunc, opaque, errp) < 0) { - g_free(block); - return NULL; - } - - return block; -} - - -int qcrypto_block_decrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return block->driver->decrypt(block, startsector, buf, len, errp); -} - - -int qcrypto_block_encrypt(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - return block->driver->encrypt(block, startsector, buf, len, errp); -} - - -QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) -{ - return block->cipher; -} - - -QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) -{ - return block->ivgen; -} - - -QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block) -{ - return block->kdfhash; -} - - -uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block) -{ - return block->payload_offset; -} - - -void qcrypto_block_free(QCryptoBlock *block) -{ - if (!block) { - return; - } - - block->driver->cleanup(block); - - qcrypto_cipher_free(block->cipher); - qcrypto_ivgen_free(block->ivgen); - g_free(block); -} - - -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - uint8_t *iv; - int ret = -1; - - iv = niv ? g_new0(uint8_t, niv) : NULL; - - while (len > 0) { - size_t nbytes; - if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { - goto cleanup; - } - - if (qcrypto_cipher_setiv(cipher, - iv, niv, - errp) < 0) { - goto cleanup; - } - } - - nbytes = len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_decrypt(cipher, buf, buf, - nbytes, errp) < 0) { - goto cleanup; - } - - startsector++; - buf += nbytes; - len -= nbytes; - } - - ret = 0; - cleanup: - g_free(iv); - return ret; -} - - -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp) -{ - uint8_t *iv; - int ret = -1; - - iv = niv ? g_new0(uint8_t, niv) : NULL; - - while (len > 0) { - size_t nbytes; - if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { - goto cleanup; - } - - if (qcrypto_cipher_setiv(cipher, - iv, niv, - errp) < 0) { - goto cleanup; - } - } - - nbytes = len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_encrypt(cipher, buf, buf, - nbytes, errp) < 0) { - goto cleanup; - } - - startsector++; - buf += nbytes; - len -= nbytes; - } - - ret = 0; - cleanup: - g_free(iv); - return ret; -} diff --git a/qemu/crypto/blockpriv.h b/qemu/crypto/blockpriv.h deleted file mode 100644 index 62970859d..000000000 --- a/qemu/crypto/blockpriv.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * QEMU Crypto block device encryption - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef QCRYPTO_BLOCK_PRIV_H__ -#define QCRYPTO_BLOCK_PRIV_H__ - -#include "crypto/block.h" - -typedef struct QCryptoBlockDriver QCryptoBlockDriver; - -struct QCryptoBlock { - QCryptoBlockFormat format; - - const QCryptoBlockDriver *driver; - void *opaque; - - QCryptoCipher *cipher; - QCryptoIVGen *ivgen; - QCryptoHashAlgorithm kdfhash; - size_t niv; - uint64_t payload_offset; /* In bytes */ -}; - -struct QCryptoBlockDriver { - int (*open)(QCryptoBlock *block, - QCryptoBlockOpenOptions *options, - QCryptoBlockReadFunc readfunc, - void *opaque, - unsigned int flags, - Error **errp); - - int (*create)(QCryptoBlock *block, - QCryptoBlockCreateOptions *options, - QCryptoBlockInitFunc initfunc, - QCryptoBlockWriteFunc writefunc, - void *opaque, - Error **errp); - - void (*cleanup)(QCryptoBlock *block); - - int (*encrypt)(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp); - int (*decrypt)(QCryptoBlock *block, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp); - - bool (*has_format)(const uint8_t *buf, - size_t buflen); -}; - - -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp); - -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t startsector, - uint8_t *buf, - size_t len, - Error **errp); - -#endif /* QCRYPTO_BLOCK_PRIV_H__ */ diff --git a/qemu/crypto/cipher-builtin.c b/qemu/crypto/cipher-builtin.c deleted file mode 100644 index 88963f65c..000000000 --- a/qemu/crypto/cipher-builtin.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * QEMU Crypto cipher built-in algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/aes.h" -#include "crypto/desrfb.h" -#include "crypto/xts.h" - -typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext; -struct QCryptoCipherBuiltinAESContext { - AES_KEY enc; - AES_KEY dec; -}; -typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES; -struct QCryptoCipherBuiltinAES { - QCryptoCipherBuiltinAESContext key; - QCryptoCipherBuiltinAESContext key_tweak; - uint8_t iv[AES_BLOCK_SIZE]; -}; -typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB; -struct QCryptoCipherBuiltinDESRFB { - uint8_t *key; - size_t nkey; -}; - -typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin; -struct QCryptoCipherBuiltin { - union { - QCryptoCipherBuiltinAES aes; - QCryptoCipherBuiltinDESRFB desrfb; - } state; - size_t blocksize; - void (*free)(QCryptoCipher *cipher); - int (*setiv)(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp); - int (*encrypt)(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp); - int (*decrypt)(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp); -}; - - -static void qcrypto_cipher_free_aes(QCryptoCipher *cipher) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - g_free(ctxt); - cipher->opaque = NULL; -} - - -static void qcrypto_cipher_aes_ecb_encrypt(AES_KEY *key, - const void *in, - void *out, - size_t len) -{ - const uint8_t *inptr = in; - uint8_t *outptr = out; - while (len) { - if (len > AES_BLOCK_SIZE) { - AES_encrypt(inptr, outptr, key); - inptr += AES_BLOCK_SIZE; - outptr += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } else { - uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; - memcpy(tmp1, inptr, len); - /* Fill with 0 to avoid valgrind uninitialized reads */ - memset(tmp1 + len, 0, sizeof(tmp1) - len); - AES_encrypt(tmp1, tmp2, key); - memcpy(outptr, tmp2, len); - len = 0; - } - } -} - - -static void qcrypto_cipher_aes_ecb_decrypt(AES_KEY *key, - const void *in, - void *out, - size_t len) -{ - const uint8_t *inptr = in; - uint8_t *outptr = out; - while (len) { - if (len > AES_BLOCK_SIZE) { - AES_decrypt(inptr, outptr, key); - inptr += AES_BLOCK_SIZE; - outptr += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } else { - uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; - memcpy(tmp1, inptr, len); - /* Fill with 0 to avoid valgrind uninitialized reads */ - memset(tmp1 + len, 0, sizeof(tmp1) - len); - AES_decrypt(tmp1, tmp2, key); - memcpy(outptr, tmp2, len); - len = 0; - } - } -} - - -static void qcrypto_cipher_aes_xts_encrypt(const void *ctx, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - const QCryptoCipherBuiltinAESContext *aesctx = ctx; - - qcrypto_cipher_aes_ecb_encrypt((AES_KEY *)&aesctx->enc, - src, dst, length); -} - - -static void qcrypto_cipher_aes_xts_decrypt(const void *ctx, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - const QCryptoCipherBuiltinAESContext *aesctx = ctx; - - qcrypto_cipher_aes_ecb_decrypt((AES_KEY *)&aesctx->dec, - src, dst, length); -} - - -static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - qcrypto_cipher_aes_ecb_encrypt(&ctxt->state.aes.key.enc, - in, out, len); - break; - case QCRYPTO_CIPHER_MODE_CBC: - AES_cbc_encrypt(in, out, len, - &ctxt->state.aes.key.enc, - ctxt->state.aes.iv, 1); - break; - case QCRYPTO_CIPHER_MODE_XTS: - xts_encrypt(&ctxt->state.aes.key, - &ctxt->state.aes.key_tweak, - qcrypto_cipher_aes_xts_encrypt, - qcrypto_cipher_aes_xts_decrypt, - ctxt->state.aes.iv, - len, out, in); - break; - default: - g_assert_not_reached(); - } - - return 0; -} - - -static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec, - in, out, len); - break; - case QCRYPTO_CIPHER_MODE_CBC: - AES_cbc_encrypt(in, out, len, - &ctxt->state.aes.key.dec, - ctxt->state.aes.iv, 0); - break; - case QCRYPTO_CIPHER_MODE_XTS: - xts_decrypt(&ctxt->state.aes.key, - &ctxt->state.aes.key_tweak, - qcrypto_cipher_aes_xts_encrypt, - qcrypto_cipher_aes_xts_decrypt, - ctxt->state.aes.iv, - len, out, in); - break; - default: - g_assert_not_reached(); - } - - return 0; -} - -static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - if (niv != AES_BLOCK_SIZE) { - error_setg(errp, "IV must be %d bytes not %zu", - AES_BLOCK_SIZE, niv); - return -1; - } - - memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE); - - return 0; -} - - - - -static int qcrypto_cipher_init_aes(QCryptoCipher *cipher, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt; - - if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC && - cipher->mode != QCRYPTO_CIPHER_MODE_ECB && - cipher->mode != QCRYPTO_CIPHER_MODE_XTS) { - error_setg(errp, "Unsupported cipher mode %d", cipher->mode); - return -1; - } - - ctxt = g_new0(QCryptoCipherBuiltin, 1); - - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) { - error_setg(errp, "Failed to set encryption key"); - goto error; - } - - if (AES_set_decrypt_key(key, nkey * 4, &ctxt->state.aes.key.dec) != 0) { - error_setg(errp, "Failed to set decryption key"); - goto error; - } - - if (AES_set_encrypt_key(key + (nkey / 2), nkey * 4, - &ctxt->state.aes.key_tweak.enc) != 0) { - error_setg(errp, "Failed to set encryption key"); - goto error; - } - - if (AES_set_decrypt_key(key + (nkey / 2), nkey * 4, - &ctxt->state.aes.key_tweak.dec) != 0) { - error_setg(errp, "Failed to set decryption key"); - goto error; - } - } else { - if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.key.enc) != 0) { - error_setg(errp, "Failed to set encryption key"); - goto error; - } - - if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.key.dec) != 0) { - error_setg(errp, "Failed to set decryption key"); - goto error; - } - } - - ctxt->blocksize = AES_BLOCK_SIZE; - ctxt->free = qcrypto_cipher_free_aes; - ctxt->setiv = qcrypto_cipher_setiv_aes; - ctxt->encrypt = qcrypto_cipher_encrypt_aes; - ctxt->decrypt = qcrypto_cipher_decrypt_aes; - - cipher->opaque = ctxt; - - return 0; - - error: - g_free(ctxt); - return -1; -} - - -static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - g_free(ctxt->state.desrfb.key); - g_free(ctxt); - cipher->opaque = NULL; -} - - -static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - size_t i; - - if (len % 8) { - error_setg(errp, "Buffer size must be multiple of 8 not %zu", - len); - return -1; - } - - deskey(ctxt->state.desrfb.key, EN0); - - for (i = 0; i < len; i += 8) { - des((void *)in + i, out + i); - } - - return 0; -} - - -static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - size_t i; - - if (len % 8) { - error_setg(errp, "Buffer size must be multiple of 8 not %zu", - len); - return -1; - } - - deskey(ctxt->state.desrfb.key, DE1); - - for (i = 0; i < len; i += 8) { - des((void *)in + i, out + i); - } - - return 0; -} - - -static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - error_setg(errp, "Setting IV is not supported"); - return -1; -} - - -static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt; - - if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) { - error_setg(errp, "Unsupported cipher mode %d", cipher->mode); - return -1; - } - - ctxt = g_new0(QCryptoCipherBuiltin, 1); - - ctxt->state.desrfb.key = g_new0(uint8_t, nkey); - memcpy(ctxt->state.desrfb.key, key, nkey); - ctxt->state.desrfb.nkey = nkey; - - ctxt->blocksize = 8; - ctxt->free = qcrypto_cipher_free_des_rfb; - ctxt->setiv = qcrypto_cipher_setiv_des_rfb; - ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb; - ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb; - - cipher->opaque = ctxt; - - return 0; -} - - -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg) -{ - switch (alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - return true; - default: - return false; - } -} - - -QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoCipher *cipher; - - cipher = g_new0(QCryptoCipher, 1); - cipher->alg = alg; - cipher->mode = mode; - - if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { - goto error; - } - - switch (cipher->alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) { - goto error; - } - break; - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) { - goto error; - } - break; - default: - error_setg(errp, - "Unsupported cipher algorithm %d", cipher->alg); - goto error; - } - - return cipher; - - error: - g_free(cipher); - return NULL; -} - -void qcrypto_cipher_free(QCryptoCipher *cipher) -{ - QCryptoCipherBuiltin *ctxt; - - if (!cipher) { - return; - } - - ctxt = cipher->opaque; - ctxt->free(cipher); - g_free(cipher); -} - - -int qcrypto_cipher_encrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - if (len % ctxt->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctxt->blocksize); - return -1; - } - - return ctxt->encrypt(cipher, in, out, len, errp); -} - - -int qcrypto_cipher_decrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - if (len % ctxt->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctxt->blocksize); - return -1; - } - - return ctxt->decrypt(cipher, in, out, len, errp); -} - - -int qcrypto_cipher_setiv(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoCipherBuiltin *ctxt = cipher->opaque; - - return ctxt->setiv(cipher, iv, niv, errp); -} diff --git a/qemu/crypto/cipher-gcrypt.c b/qemu/crypto/cipher-gcrypt.c deleted file mode 100644 index ede2f70df..000000000 --- a/qemu/crypto/cipher-gcrypt.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * QEMU Crypto cipher libgcrypt algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/xts.h" - -#include <gcrypt.h> - - -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg) -{ - switch (alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_CAST5_128: - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - return true; - default: - return false; - } -} - -typedef struct QCryptoCipherGcrypt QCryptoCipherGcrypt; -struct QCryptoCipherGcrypt { - gcry_cipher_hd_t handle; - gcry_cipher_hd_t tweakhandle; - size_t blocksize; - uint8_t *iv; -}; - -QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoCipher *cipher; - QCryptoCipherGcrypt *ctx; - gcry_error_t err; - int gcryalg, gcrymode; - - switch (mode) { - case QCRYPTO_CIPHER_MODE_ECB: - case QCRYPTO_CIPHER_MODE_XTS: - gcrymode = GCRY_CIPHER_MODE_ECB; - break; - case QCRYPTO_CIPHER_MODE_CBC: - gcrymode = GCRY_CIPHER_MODE_CBC; - break; - default: - error_setg(errp, "Unsupported cipher mode %d", mode); - return NULL; - } - - if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { - return NULL; - } - - switch (alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - gcryalg = GCRY_CIPHER_DES; - break; - - case QCRYPTO_CIPHER_ALG_AES_128: - gcryalg = GCRY_CIPHER_AES128; - break; - - case QCRYPTO_CIPHER_ALG_AES_192: - gcryalg = GCRY_CIPHER_AES192; - break; - - case QCRYPTO_CIPHER_ALG_AES_256: - gcryalg = GCRY_CIPHER_AES256; - break; - - case QCRYPTO_CIPHER_ALG_CAST5_128: - gcryalg = GCRY_CIPHER_CAST5; - break; - - case QCRYPTO_CIPHER_ALG_SERPENT_128: - gcryalg = GCRY_CIPHER_SERPENT128; - break; - - case QCRYPTO_CIPHER_ALG_SERPENT_192: - gcryalg = GCRY_CIPHER_SERPENT192; - break; - - case QCRYPTO_CIPHER_ALG_SERPENT_256: - gcryalg = GCRY_CIPHER_SERPENT256; - break; - - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - gcryalg = GCRY_CIPHER_TWOFISH128; - break; - - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - gcryalg = GCRY_CIPHER_TWOFISH; - break; - - default: - error_setg(errp, "Unsupported cipher algorithm %d", alg); - return NULL; - } - - cipher = g_new0(QCryptoCipher, 1); - cipher->alg = alg; - cipher->mode = mode; - - ctx = g_new0(QCryptoCipherGcrypt, 1); - - err = gcry_cipher_open(&ctx->handle, gcryalg, gcrymode, 0); - if (err != 0) { - error_setg(errp, "Cannot initialize cipher: %s", - gcry_strerror(err)); - goto error; - } - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - err = gcry_cipher_open(&ctx->tweakhandle, gcryalg, gcrymode, 0); - if (err != 0) { - error_setg(errp, "Cannot initialize cipher: %s", - gcry_strerror(err)); - goto error; - } - } - - if (cipher->alg == QCRYPTO_CIPHER_ALG_DES_RFB) { - /* We're using standard DES cipher from gcrypt, so we need - * to munge the key so that the results are the same as the - * bizarre RFB variant of DES :-) - */ - uint8_t *rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey); - err = gcry_cipher_setkey(ctx->handle, rfbkey, nkey); - g_free(rfbkey); - ctx->blocksize = 8; - } else { - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - nkey /= 2; - err = gcry_cipher_setkey(ctx->handle, key, nkey); - if (err != 0) { - error_setg(errp, "Cannot set key: %s", - gcry_strerror(err)); - goto error; - } - err = gcry_cipher_setkey(ctx->tweakhandle, key + nkey, nkey); - } else { - err = gcry_cipher_setkey(ctx->handle, key, nkey); - } - if (err != 0) { - error_setg(errp, "Cannot set key: %s", - gcry_strerror(err)); - goto error; - } - switch (cipher->alg) { - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - ctx->blocksize = 16; - break; - case QCRYPTO_CIPHER_ALG_CAST5_128: - ctx->blocksize = 8; - break; - default: - g_assert_not_reached(); - } - } - - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - ctx->iv = g_new0(uint8_t, ctx->blocksize); - } - - cipher->opaque = ctx; - return cipher; - - error: - gcry_cipher_close(ctx->handle); - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - gcry_cipher_close(ctx->tweakhandle); - } - g_free(ctx); - g_free(cipher); - return NULL; -} - - -void qcrypto_cipher_free(QCryptoCipher *cipher) -{ - QCryptoCipherGcrypt *ctx; - if (!cipher) { - return; - } - ctx = cipher->opaque; - gcry_cipher_close(ctx->handle); - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - gcry_cipher_close(ctx->tweakhandle); - } - g_free(ctx->iv); - g_free(ctx); - g_free(cipher); -} - - -static void qcrypto_gcrypt_xts_encrypt(const void *ctx, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - gcry_error_t err; - err = gcry_cipher_encrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); - g_assert(err == 0); -} - -static void qcrypto_gcrypt_xts_decrypt(const void *ctx, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - gcry_error_t err; - err = gcry_cipher_decrypt((gcry_cipher_hd_t)ctx, dst, length, src, length); - g_assert(err == 0); -} - -int qcrypto_cipher_encrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherGcrypt *ctx = cipher->opaque; - gcry_error_t err; - - if (len % ctx->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - xts_encrypt(ctx->handle, ctx->tweakhandle, - qcrypto_gcrypt_xts_encrypt, - qcrypto_gcrypt_xts_decrypt, - ctx->iv, len, out, in); - } else { - err = gcry_cipher_encrypt(ctx->handle, - out, len, - in, len); - if (err != 0) { - error_setg(errp, "Cannot encrypt data: %s", - gcry_strerror(err)); - return -1; - } - } - - return 0; -} - - -int qcrypto_cipher_decrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherGcrypt *ctx = cipher->opaque; - gcry_error_t err; - - if (len % ctx->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) { - xts_decrypt(ctx->handle, ctx->tweakhandle, - qcrypto_gcrypt_xts_encrypt, - qcrypto_gcrypt_xts_decrypt, - ctx->iv, len, out, in); - } else { - err = gcry_cipher_decrypt(ctx->handle, - out, len, - in, len); - if (err != 0) { - error_setg(errp, "Cannot decrypt data: %s", - gcry_strerror(err)); - return -1; - } - } - - return 0; -} - -int qcrypto_cipher_setiv(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoCipherGcrypt *ctx = cipher->opaque; - gcry_error_t err; - - if (niv != ctx->blocksize) { - error_setg(errp, "Expected IV size %zu not %zu", - ctx->blocksize, niv); - return -1; - } - - if (ctx->iv) { - memcpy(ctx->iv, iv, niv); - } else { - gcry_cipher_reset(ctx->handle); - err = gcry_cipher_setiv(ctx->handle, iv, niv); - if (err != 0) { - error_setg(errp, "Cannot set IV: %s", - gcry_strerror(err)); - return -1; - } - } - - return 0; -} diff --git a/qemu/crypto/cipher-nettle.c b/qemu/crypto/cipher-nettle.c deleted file mode 100644 index 70909fb7f..000000000 --- a/qemu/crypto/cipher-nettle.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * QEMU Crypto cipher nettle algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/xts.h" - -#include <nettle/nettle-types.h> -#include <nettle/aes.h> -#include <nettle/des.h> -#include <nettle/cbc.h> -#include <nettle/cast128.h> -#include <nettle/serpent.h> -#include <nettle/twofish.h> - -typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx, - size_t length, - uint8_t *dst, - const uint8_t *src); - -#if CONFIG_NETTLE_VERSION_MAJOR < 3 -typedef nettle_crypt_func * QCryptoCipherNettleFuncNative; -typedef void * cipher_ctx_t; -typedef unsigned cipher_length_t; - -#define cast5_set_key cast128_set_key -#else -typedef nettle_cipher_func * QCryptoCipherNettleFuncNative; -typedef const void * cipher_ctx_t; -typedef size_t cipher_length_t; -#endif - -typedef struct QCryptoNettleAES { - struct aes_ctx enc; - struct aes_ctx dec; -} QCryptoNettleAES; - -static void aes_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES *aesctx = ctx; - aes_encrypt(&aesctx->enc, length, dst, src); -} - -static void aes_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES *aesctx = ctx; - aes_decrypt(&aesctx->dec, length, dst, src); -} - -static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - des_encrypt(ctx, length, dst, src); -} - -static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - des_decrypt(ctx, length, dst, src); -} - -static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_encrypt(ctx, length, dst, src); -} - -static void cast128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_decrypt(ctx, length, dst, src); -} - -static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_encrypt(ctx, length, dst, src); -} - -static void serpent_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_decrypt(ctx, length, dst, src); -} - -static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_encrypt(ctx, length, dst, src); -} - -static void twofish_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_decrypt(ctx, length, dst, src); -} - -static void aes_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES *aesctx = ctx; - aes_encrypt(&aesctx->enc, length, dst, src); -} - -static void aes_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - const QCryptoNettleAES *aesctx = ctx; - aes_decrypt(&aesctx->dec, length, dst, src); -} - -static void des_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des_encrypt(ctx, length, dst, src); -} - -static void des_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - des_decrypt(ctx, length, dst, src); -} - -static void cast128_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_encrypt(ctx, length, dst, src); -} - -static void cast128_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - cast128_decrypt(ctx, length, dst, src); -} - -static void serpent_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_encrypt(ctx, length, dst, src); -} - -static void serpent_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - serpent_decrypt(ctx, length, dst, src); -} - -static void twofish_encrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_encrypt(ctx, length, dst, src); -} - -static void twofish_decrypt_wrapper(const void *ctx, size_t length, - uint8_t *dst, const uint8_t *src) -{ - twofish_decrypt(ctx, length, dst, src); -} - -typedef struct QCryptoCipherNettle QCryptoCipherNettle; -struct QCryptoCipherNettle { - /* Primary cipher context for all modes */ - void *ctx; - /* Second cipher context for XTS mode only */ - void *ctx_tweak; - /* Cipher callbacks for both contexts */ - QCryptoCipherNettleFuncNative alg_encrypt_native; - QCryptoCipherNettleFuncNative alg_decrypt_native; - QCryptoCipherNettleFuncWrapper alg_encrypt_wrapper; - QCryptoCipherNettleFuncWrapper alg_decrypt_wrapper; - - uint8_t *iv; - size_t blocksize; -}; - -bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg) -{ - switch (alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - case QCRYPTO_CIPHER_ALG_CAST5_128: - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - return true; - default: - return false; - } -} - - -QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoCipher *cipher; - QCryptoCipherNettle *ctx; - uint8_t *rfbkey; - - switch (mode) { - case QCRYPTO_CIPHER_MODE_ECB: - case QCRYPTO_CIPHER_MODE_CBC: - case QCRYPTO_CIPHER_MODE_XTS: - break; - default: - error_setg(errp, "Unsupported cipher mode %d", mode); - return NULL; - } - - if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { - return NULL; - } - - cipher = g_new0(QCryptoCipher, 1); - cipher->alg = alg; - cipher->mode = mode; - - ctx = g_new0(QCryptoCipherNettle, 1); - - switch (alg) { - case QCRYPTO_CIPHER_ALG_DES_RFB: - ctx->ctx = g_new0(struct des_ctx, 1); - rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey); - des_set_key(ctx->ctx, rfbkey); - g_free(rfbkey); - - ctx->alg_encrypt_native = des_encrypt_native; - ctx->alg_decrypt_native = des_decrypt_native; - ctx->alg_encrypt_wrapper = des_encrypt_wrapper; - ctx->alg_decrypt_wrapper = des_decrypt_wrapper; - - ctx->blocksize = DES_BLOCK_SIZE; - break; - - case QCRYPTO_CIPHER_ALG_AES_128: - case QCRYPTO_CIPHER_ALG_AES_192: - case QCRYPTO_CIPHER_ALG_AES_256: - ctx->ctx = g_new0(QCryptoNettleAES, 1); - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak = g_new0(QCryptoNettleAES, 1); - - nkey /= 2; - aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc, - nkey, key); - aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec, - nkey, key); - - aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->enc, - nkey, key + nkey); - aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->dec, - nkey, key + nkey); - } else { - aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc, - nkey, key); - aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec, - nkey, key); - } - - ctx->alg_encrypt_native = aes_encrypt_native; - ctx->alg_decrypt_native = aes_decrypt_native; - ctx->alg_encrypt_wrapper = aes_encrypt_wrapper; - ctx->alg_decrypt_wrapper = aes_decrypt_wrapper; - - ctx->blocksize = AES_BLOCK_SIZE; - break; - - case QCRYPTO_CIPHER_ALG_CAST5_128: - ctx->ctx = g_new0(struct cast128_ctx, 1); - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak = g_new0(struct cast128_ctx, 1); - - nkey /= 2; - cast5_set_key(ctx->ctx, nkey, key); - cast5_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - cast5_set_key(ctx->ctx, nkey, key); - } - - ctx->alg_encrypt_native = cast128_encrypt_native; - ctx->alg_decrypt_native = cast128_decrypt_native; - ctx->alg_encrypt_wrapper = cast128_encrypt_wrapper; - ctx->alg_decrypt_wrapper = cast128_decrypt_wrapper; - - ctx->blocksize = CAST128_BLOCK_SIZE; - break; - - case QCRYPTO_CIPHER_ALG_SERPENT_128: - case QCRYPTO_CIPHER_ALG_SERPENT_192: - case QCRYPTO_CIPHER_ALG_SERPENT_256: - ctx->ctx = g_new0(struct serpent_ctx, 1); - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak = g_new0(struct serpent_ctx, 1); - - nkey /= 2; - serpent_set_key(ctx->ctx, nkey, key); - serpent_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - serpent_set_key(ctx->ctx, nkey, key); - } - - ctx->alg_encrypt_native = serpent_encrypt_native; - ctx->alg_decrypt_native = serpent_decrypt_native; - ctx->alg_encrypt_wrapper = serpent_encrypt_wrapper; - ctx->alg_decrypt_wrapper = serpent_decrypt_wrapper; - - ctx->blocksize = SERPENT_BLOCK_SIZE; - break; - - case QCRYPTO_CIPHER_ALG_TWOFISH_128: - case QCRYPTO_CIPHER_ALG_TWOFISH_192: - case QCRYPTO_CIPHER_ALG_TWOFISH_256: - ctx->ctx = g_new0(struct twofish_ctx, 1); - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - ctx->ctx_tweak = g_new0(struct twofish_ctx, 1); - - nkey /= 2; - twofish_set_key(ctx->ctx, nkey, key); - twofish_set_key(ctx->ctx_tweak, nkey, key + nkey); - } else { - twofish_set_key(ctx->ctx, nkey, key); - } - - ctx->alg_encrypt_native = twofish_encrypt_native; - ctx->alg_decrypt_native = twofish_decrypt_native; - ctx->alg_encrypt_wrapper = twofish_encrypt_wrapper; - ctx->alg_decrypt_wrapper = twofish_decrypt_wrapper; - - ctx->blocksize = TWOFISH_BLOCK_SIZE; - break; - - default: - error_setg(errp, "Unsupported cipher algorithm %d", alg); - goto error; - } - - ctx->iv = g_new0(uint8_t, ctx->blocksize); - cipher->opaque = ctx; - - return cipher; - - error: - g_free(cipher); - g_free(ctx); - return NULL; -} - - -void qcrypto_cipher_free(QCryptoCipher *cipher) -{ - QCryptoCipherNettle *ctx; - - if (!cipher) { - return; - } - - ctx = cipher->opaque; - g_free(ctx->iv); - g_free(ctx->ctx); - g_free(ctx->ctx_tweak); - g_free(ctx); - g_free(cipher); -} - - -int qcrypto_cipher_encrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherNettle *ctx = cipher->opaque; - - if (len % ctx->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - ctx->alg_encrypt_wrapper(ctx->ctx, len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_CBC: - cbc_encrypt(ctx->ctx, ctx->alg_encrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_XTS: - xts_encrypt(ctx->ctx, ctx->ctx_tweak, - ctx->alg_encrypt_wrapper, ctx->alg_encrypt_wrapper, - ctx->iv, len, out, in); - break; - - default: - error_setg(errp, "Unsupported cipher algorithm %d", - cipher->alg); - return -1; - } - return 0; -} - - -int qcrypto_cipher_decrypt(QCryptoCipher *cipher, - const void *in, - void *out, - size_t len, - Error **errp) -{ - QCryptoCipherNettle *ctx = cipher->opaque; - - if (len % ctx->blocksize) { - error_setg(errp, "Length %zu must be a multiple of block size %zu", - len, ctx->blocksize); - return -1; - } - - switch (cipher->mode) { - case QCRYPTO_CIPHER_MODE_ECB: - ctx->alg_decrypt_wrapper(ctx->ctx, len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_CBC: - cbc_decrypt(ctx->ctx, ctx->alg_decrypt_native, - ctx->blocksize, ctx->iv, - len, out, in); - break; - - case QCRYPTO_CIPHER_MODE_XTS: - if (ctx->blocksize != XTS_BLOCK_SIZE) { - error_setg(errp, "Block size must be %d not %zu", - XTS_BLOCK_SIZE, ctx->blocksize); - return -1; - } - xts_decrypt(ctx->ctx, ctx->ctx_tweak, - ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper, - ctx->iv, len, out, in); - break; - - default: - error_setg(errp, "Unsupported cipher algorithm %d", - cipher->alg); - return -1; - } - return 0; -} - -int qcrypto_cipher_setiv(QCryptoCipher *cipher, - const uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoCipherNettle *ctx = cipher->opaque; - if (niv != ctx->blocksize) { - error_setg(errp, "Expected IV size %zu not %zu", - ctx->blocksize, niv); - return -1; - } - memcpy(ctx->iv, iv, niv); - return 0; -} diff --git a/qemu/crypto/cipher.c b/qemu/crypto/cipher.c deleted file mode 100644 index cafb45436..000000000 --- a/qemu/crypto/cipher.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * QEMU Crypto cipher algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/cipher.h" - - -static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = { - [QCRYPTO_CIPHER_ALG_AES_128] = 16, - [QCRYPTO_CIPHER_ALG_AES_192] = 24, - [QCRYPTO_CIPHER_ALG_AES_256] = 32, - [QCRYPTO_CIPHER_ALG_DES_RFB] = 8, - [QCRYPTO_CIPHER_ALG_CAST5_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_192] = 24, - [QCRYPTO_CIPHER_ALG_SERPENT_256] = 32, - [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 24, - [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 32, -}; - -static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = { - [QCRYPTO_CIPHER_ALG_AES_128] = 16, - [QCRYPTO_CIPHER_ALG_AES_192] = 16, - [QCRYPTO_CIPHER_ALG_AES_256] = 16, - [QCRYPTO_CIPHER_ALG_DES_RFB] = 8, - [QCRYPTO_CIPHER_ALG_CAST5_128] = 8, - [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_192] = 16, - [QCRYPTO_CIPHER_ALG_SERPENT_256] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_128] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_192] = 16, - [QCRYPTO_CIPHER_ALG_TWOFISH_256] = 16, -}; - -static bool mode_need_iv[QCRYPTO_CIPHER_MODE__MAX] = { - [QCRYPTO_CIPHER_MODE_ECB] = false, - [QCRYPTO_CIPHER_MODE_CBC] = true, - [QCRYPTO_CIPHER_MODE_XTS] = true, -}; - - -size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg) -{ - if (alg >= G_N_ELEMENTS(alg_key_len)) { - return 0; - } - return alg_block_len[alg]; -} - - -size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg) -{ - if (alg >= G_N_ELEMENTS(alg_key_len)) { - return 0; - } - return alg_key_len[alg]; -} - - -size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode) -{ - if (alg >= G_N_ELEMENTS(alg_block_len)) { - return 0; - } - if (mode >= G_N_ELEMENTS(mode_need_iv)) { - return 0; - } - - if (mode_need_iv[mode]) { - return alg_block_len[alg]; - } - return 0; -} - - -static bool -qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg, - QCryptoCipherMode mode, - size_t nkey, - Error **errp) -{ - if ((unsigned)alg >= QCRYPTO_CIPHER_ALG__MAX) { - error_setg(errp, "Cipher algorithm %d out of range", - alg); - return false; - } - - if (mode == QCRYPTO_CIPHER_MODE_XTS) { - if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) { - error_setg(errp, "XTS mode not compatible with DES-RFB"); - return false; - } - if (nkey % 2) { - error_setg(errp, "XTS cipher key length should be a multiple of 2"); - return false; - } - - if (alg_key_len[alg] != (nkey / 2)) { - error_setg(errp, "Cipher key length %zu should be %zu", - nkey, alg_key_len[alg] * 2); - return false; - } - } else { - if (alg_key_len[alg] != nkey) { - error_setg(errp, "Cipher key length %zu should be %zu", - nkey, alg_key_len[alg]); - return false; - } - } - return true; -} - -#if defined(CONFIG_GCRYPT) || defined(CONFIG_NETTLE) -static uint8_t * -qcrypto_cipher_munge_des_rfb_key(const uint8_t *key, - size_t nkey) -{ - uint8_t *ret = g_new0(uint8_t, nkey); - size_t i; - for (i = 0; i < nkey; i++) { - uint8_t r = key[i]; - r = (r & 0xf0) >> 4 | (r & 0x0f) << 4; - r = (r & 0xcc) >> 2 | (r & 0x33) << 2; - r = (r & 0xaa) >> 1 | (r & 0x55) << 1; - ret[i] = r; - } - return ret; -} -#endif /* CONFIG_GCRYPT || CONFIG_NETTLE */ - -#ifdef CONFIG_GCRYPT -#include "crypto/cipher-gcrypt.c" -#elif defined CONFIG_NETTLE -#include "crypto/cipher-nettle.c" -#else -#include "crypto/cipher-builtin.c" -#endif diff --git a/qemu/crypto/desrfb.c b/qemu/crypto/desrfb.c deleted file mode 100644 index ec47dea3b..000000000 --- a/qemu/crypto/desrfb.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * This is D3DES (V5.09) by Richard Outerbridge with the double and - * triple-length support removed for use in VNC. Also the bytebit[] array - * has been reversed so that the most significant bit in each byte of the - * key is ignored, not the least significant. - * - * These changes are: - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -/* D3DES (V5.09) - - * - * A portable, public domain, version of the Data Encryption Standard. - * - * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. - * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation - * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis - * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, - * for humouring me on. - * - * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. - * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. - */ - -#include "qemu/osdep.h" -#include "crypto/desrfb.h" - -static void scrunch(unsigned char *, unsigned long *); -static void unscrun(unsigned long *, unsigned char *); -static void desfunc(unsigned long *, unsigned long *); -static void cookey(unsigned long *); - -static unsigned long KnL[32] = { 0L }; - -static const unsigned short bytebit[8] = { - 01, 02, 04, 010, 020, 040, 0100, 0200 }; - -static const unsigned long bigbyte[24] = { - 0x800000L, 0x400000L, 0x200000L, 0x100000L, - 0x80000L, 0x40000L, 0x20000L, 0x10000L, - 0x8000L, 0x4000L, 0x2000L, 0x1000L, - 0x800L, 0x400L, 0x200L, 0x100L, - 0x80L, 0x40L, 0x20L, 0x10L, - 0x8L, 0x4L, 0x2L, 0x1L }; - -/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ - -static const unsigned char pc1[56] = { - 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; - -static const unsigned char totrot[16] = { - 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; - -static const unsigned char pc2[48] = { - 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; - -/* Thanks to James Gillogly & Phil Karn! */ -void deskey(unsigned char *key, int edf) -{ - register int i, j, l, m, n; - unsigned char pc1m[56], pcr[56]; - unsigned long kn[32]; - - for ( j = 0; j < 56; j++ ) { - l = pc1[j]; - m = l & 07; - pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; - } - for( i = 0; i < 16; i++ ) { - if( edf == DE1 ) m = (15 - i) << 1; - else m = i << 1; - n = m + 1; - kn[m] = kn[n] = 0L; - for( j = 0; j < 28; j++ ) { - l = j + totrot[i]; - if( l < 28 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 28; j < 56; j++ ) { - l = j + totrot[i]; - if( l < 56 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 0; j < 24; j++ ) { - if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; - if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; - } - } - cookey(kn); - return; - } - -static void cookey(register unsigned long *raw1) -{ - register unsigned long *cook, *raw0; - unsigned long dough[32]; - register int i; - - cook = dough; - for( i = 0; i < 16; i++, raw1++ ) { - raw0 = raw1++; - *cook = (*raw0 & 0x00fc0000L) << 6; - *cook |= (*raw0 & 0x00000fc0L) << 10; - *cook |= (*raw1 & 0x00fc0000L) >> 10; - *cook++ |= (*raw1 & 0x00000fc0L) >> 6; - *cook = (*raw0 & 0x0003f000L) << 12; - *cook |= (*raw0 & 0x0000003fL) << 16; - *cook |= (*raw1 & 0x0003f000L) >> 4; - *cook++ |= (*raw1 & 0x0000003fL); - } - usekey(dough); - return; - } - -void usekey(register unsigned long *from) -{ - register unsigned long *to, *endp; - - to = KnL, endp = &KnL[32]; - while( to < endp ) *to++ = *from++; - return; - } - -void des(unsigned char *inblock, unsigned char *outblock) -{ - unsigned long work[2]; - - scrunch(inblock, work); - desfunc(work, KnL); - unscrun(work, outblock); - return; - } - -static void scrunch(register unsigned char *outof, register unsigned long *into) -{ - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into++ |= (*outof++ & 0xffL); - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into |= (*outof & 0xffL); - return; - } - -static void unscrun(register unsigned long *outof, register unsigned char *into) -{ - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into++ = (unsigned char)(*outof++ & 0xffL); - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into = (unsigned char)(*outof & 0xffL); - return; - } - -static const unsigned long SP1[64] = { - 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, - 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, - 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, - 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, - 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, - 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, - 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, - 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, - 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, - 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, - 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, - 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, - 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, - 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; - -static const unsigned long SP2[64] = { - 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, - 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, - 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, - 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, - 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, - 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, - 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, - 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, - 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, - 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, - 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, - 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, - 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, - 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, - 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, - 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; - -static const unsigned long SP3[64] = { - 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, - 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, - 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, - 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, - 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, - 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, - 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, - 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, - 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, - 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, - 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, - 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, - 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, - 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, - 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, - 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; - -static const unsigned long SP4[64] = { - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, - 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, - 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, - 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, - 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, - 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, - 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, - 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, - 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; - -static const unsigned long SP5[64] = { - 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, - 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, - 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, - 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, - 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, - 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, - 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, - 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, - 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, - 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, - 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, - 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, - 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, - 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, - 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, - 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; - -static const unsigned long SP6[64] = { - 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, - 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, - 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, - 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, - 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, - 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, - 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, - 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, - 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, - 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, - 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, - 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, - 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, - 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; - -static const unsigned long SP7[64] = { - 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, - 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, - 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, - 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, - 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, - 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, - 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, - 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, - 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, - 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, - 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, - 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, - 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, - 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, - 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, - 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; - -static const unsigned long SP8[64] = { - 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, - 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, - 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, - 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, - 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, - 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, - 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, - 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, - 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, - 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, - 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, - 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, - 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, - 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, - 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, - 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; - -static void desfunc(register unsigned long *block, register unsigned long *keys) -{ - register unsigned long fval, work, right, leftt; - register int round; - - leftt = block[0]; - right = block[1]; - work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; - right ^= work; - leftt ^= (work << 4); - work = ((leftt >> 16) ^ right) & 0x0000ffffL; - right ^= work; - leftt ^= (work << 16); - work = ((right >> 2) ^ leftt) & 0x33333333L; - leftt ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ leftt) & 0x00ff00ffL; - leftt ^= work; - right ^= (work << 8); - right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; - - for( round = 0; round < 8; round++ ) { - work = (right << 28) | (right >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = right ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - leftt ^= fval; - work = (leftt << 28) | (leftt >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = leftt ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - right ^= fval; - } - - right = (right << 31) | (right >> 1); - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = (leftt << 31) | (leftt >> 1); - work = ((leftt >> 8) ^ right) & 0x00ff00ffL; - right ^= work; - leftt ^= (work << 8); - work = ((leftt >> 2) ^ right) & 0x33333333L; - right ^= work; - leftt ^= (work << 2); - work = ((right >> 16) ^ leftt) & 0x0000ffffL; - leftt ^= work; - right ^= (work << 16); - work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; - leftt ^= work; - right ^= (work << 4); - *block++ = right; - *block = leftt; - return; - } - -/* Validation sets: - * - * Single-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef - * Plain : 0123 4567 89ab cde7 - * Cipher : c957 4425 6a5e d31d - * - * Double-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 - * Plain : 0123 4567 89ab cde7 - * Cipher : 7f1d 0a77 826b 8aff - * - * Double-length key, double-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 - * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff - * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 - * - * Triple-length key, single-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 - * Plain : 0123 4567 89ab cde7 - * Cipher : de0b 7c06 ae5e 0ed5 - * - * Triple-length key, double-length plaintext - - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 - * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff - * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 - * - * d3des V5.0a rwo 9208.07 18:44 Graven Imagery - **********************************************************************/ diff --git a/qemu/crypto/hash.c b/qemu/crypto/hash.c deleted file mode 100644 index b90af3495..000000000 --- a/qemu/crypto/hash.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * QEMU Crypto hash algorithms - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/hash.h" - -#ifdef CONFIG_GNUTLS_HASH -#include <gnutls/gnutls.h> -#include <gnutls/crypto.h> -#endif - - -static size_t qcrypto_hash_alg_size[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = 16, - [QCRYPTO_HASH_ALG_SHA1] = 20, - [QCRYPTO_HASH_ALG_SHA256] = 32, -}; - -size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg) -{ - if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_size)) { - return 0; - } - return qcrypto_hash_alg_size[alg]; -} - - -#ifdef CONFIG_GNUTLS_HASH -static int qcrypto_hash_alg_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GNUTLS_DIG_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GNUTLS_DIG_SHA1, - [QCRYPTO_HASH_ALG_SHA256] = GNUTLS_DIG_SHA256, -}; - -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg) -{ - if (alg < G_N_ELEMENTS(qcrypto_hash_alg_map)) { - return true; - } - return false; -} - - -int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - uint8_t **result, - size_t *resultlen, - Error **errp) -{ - int i, ret; - gnutls_hash_hd_t dig; - - if (alg >= G_N_ELEMENTS(qcrypto_hash_alg_map)) { - error_setg(errp, - "Unknown hash algorithm %d", - alg); - return -1; - } - - ret = gnutls_hash_init(&dig, qcrypto_hash_alg_map[alg]); - - if (ret < 0) { - error_setg(errp, - "Unable to initialize hash algorithm: %s", - gnutls_strerror(ret)); - return -1; - } - - for (i = 0; i < niov; i++) { - ret = gnutls_hash(dig, iov[i].iov_base, iov[i].iov_len); - if (ret < 0) { - error_setg(errp, - "Unable process hash data: %s", - gnutls_strerror(ret)); - goto error; - } - } - - ret = gnutls_hash_get_len(qcrypto_hash_alg_map[alg]); - if (ret <= 0) { - error_setg(errp, - "Unable to get hash length: %s", - gnutls_strerror(ret)); - goto error; - } - if (*resultlen == 0) { - *resultlen = ret; - *result = g_new0(uint8_t, *resultlen); - } else if (*resultlen != ret) { - error_setg(errp, - "Result buffer size %zu is smaller than hash %d", - *resultlen, ret); - goto error; - } - - gnutls_hash_deinit(dig, *result); - return 0; - - error: - gnutls_hash_deinit(dig, NULL); - return -1; -} - -#else /* ! CONFIG_GNUTLS_HASH */ - -gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg G_GNUC_UNUSED) -{ - return false; -} - -int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg, - const struct iovec *iov G_GNUC_UNUSED, - size_t niov G_GNUC_UNUSED, - uint8_t **result G_GNUC_UNUSED, - size_t *resultlen G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, - "Hash algorithm %d not supported without GNUTLS", - alg); - return -1; -} - -#endif /* ! CONFIG_GNUTLS_HASH */ - -int qcrypto_hash_bytes(QCryptoHashAlgorithm alg, - const char *buf, - size_t len, - uint8_t **result, - size_t *resultlen, - Error **errp) -{ - struct iovec iov = { .iov_base = (char *)buf, - .iov_len = len }; - return qcrypto_hash_bytesv(alg, &iov, 1, result, resultlen, errp); -} - -static const char hex[] = "0123456789abcdef"; - -int qcrypto_hash_digestv(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - char **digest, - Error **errp) -{ - uint8_t *result = NULL; - size_t resultlen = 0; - size_t i; - - if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) { - return -1; - } - - *digest = g_new0(char, (resultlen * 2) + 1); - for (i = 0 ; i < resultlen ; i++) { - (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf]; - (*digest)[(i * 2) + 1] = hex[result[i] & 0xf]; - } - (*digest)[resultlen * 2] = '\0'; - g_free(result); - return 0; -} - -int qcrypto_hash_digest(QCryptoHashAlgorithm alg, - const char *buf, - size_t len, - char **digest, - Error **errp) -{ - struct iovec iov = { .iov_base = (char *)buf, .iov_len = len }; - - return qcrypto_hash_digestv(alg, &iov, 1, digest, errp); -} - -int qcrypto_hash_base64v(QCryptoHashAlgorithm alg, - const struct iovec *iov, - size_t niov, - char **base64, - Error **errp) -{ - uint8_t *result = NULL; - size_t resultlen = 0; - - if (qcrypto_hash_bytesv(alg, iov, niov, &result, &resultlen, errp) < 0) { - return -1; - } - - *base64 = g_base64_encode(result, resultlen); - g_free(result); - return 0; -} - -int qcrypto_hash_base64(QCryptoHashAlgorithm alg, - const char *buf, - size_t len, - char **base64, - Error **errp) -{ - struct iovec iov = { .iov_base = (char *)buf, .iov_len = len }; - - return qcrypto_hash_base64v(alg, &iov, 1, base64, errp); -} diff --git a/qemu/crypto/init.c b/qemu/crypto/init.c deleted file mode 100644 index 1e564d949..000000000 --- a/qemu/crypto/init.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * QEMU Crypto initialization - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/init.h" -#include "qapi/error.h" -#include "qemu/thread.h" - -#ifdef CONFIG_GNUTLS -#include <gnutls/gnutls.h> -#include <gnutls/crypto.h> -#endif - -#ifdef CONFIG_GCRYPT -#include <gcrypt.h> -#endif - -/* #define DEBUG_GNUTLS */ - -/* - * If GNUTLS is built against GCrypt then - * - * - When GNUTLS >= 2.12, we must not initialize gcrypt threading - * because GNUTLS will do that itself - * - When GNUTLS < 2.12 we must always initialize gcrypt threading - * - When GNUTLS is disabled we must always initialize gcrypt threading - * - * But.... - * - * When gcrypt >= 1.6.0 we must not initialize gcrypt threading - * because gcrypt will do that itself. - * - * So we need to init gcrypt threading if - * - * - gcrypt < 1.6.0 - * AND - * - gnutls < 2.12 - * OR - * - gnutls is disabled - * - */ - -#if (defined(CONFIG_GCRYPT) && \ - (!defined(CONFIG_GNUTLS) || \ - !defined(GNUTLS_VERSION_NUMBER) || \ - (GNUTLS_VERSION_NUMBER < 0x020c00)) && \ - (!defined(GCRYPT_VERSION_NUMBER) || \ - (GCRYPT_VERSION_NUMBER < 0x010600))) -#define QCRYPTO_INIT_GCRYPT_THREADS -#else -#undef QCRYPTO_INIT_GCRYPT_THREADS -#endif - -#ifdef DEBUG_GNUTLS -static void qcrypto_gnutls_log(int level, const char *str) -{ - fprintf(stderr, "%d: %s", level, str); -} -#endif - -#ifdef QCRYPTO_INIT_GCRYPT_THREADS -static int qcrypto_gcrypt_mutex_init(void **priv) -{ \ - QemuMutex *lock = NULL; - lock = g_new0(QemuMutex, 1); - qemu_mutex_init(lock); - *priv = lock; - return 0; -} - -static int qcrypto_gcrypt_mutex_destroy(void **priv) -{ - QemuMutex *lock = *priv; - qemu_mutex_destroy(lock); - g_free(lock); - return 0; -} - -static int qcrypto_gcrypt_mutex_lock(void **priv) -{ - QemuMutex *lock = *priv; - qemu_mutex_lock(lock); - return 0; -} - -static int qcrypto_gcrypt_mutex_unlock(void **priv) -{ - QemuMutex *lock = *priv; - qemu_mutex_unlock(lock); - return 0; -} - -static struct gcry_thread_cbs qcrypto_gcrypt_thread_impl = { - (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), - NULL, - qcrypto_gcrypt_mutex_init, - qcrypto_gcrypt_mutex_destroy, - qcrypto_gcrypt_mutex_lock, - qcrypto_gcrypt_mutex_unlock, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -#endif /* QCRYPTO_INIT_GCRYPT */ - -int qcrypto_init(Error **errp) -{ -#ifdef CONFIG_GNUTLS - int ret; - ret = gnutls_global_init(); - if (ret < 0) { - error_setg(errp, - "Unable to initialize GNUTLS library: %s", - gnutls_strerror(ret)); - return -1; - } -#ifdef DEBUG_GNUTLS - gnutls_global_set_log_level(10); - gnutls_global_set_log_function(qcrypto_gnutls_log); -#endif -#endif - -#ifdef CONFIG_GCRYPT - if (!gcry_check_version(GCRYPT_VERSION)) { - error_setg(errp, "Unable to initialize gcrypt"); - return -1; - } -#ifdef QCRYPTO_INIT_GCRYPT_THREADS - gcry_control(GCRYCTL_SET_THREAD_CBS, &qcrypto_gcrypt_thread_impl); -#endif /* QCRYPTO_INIT_GCRYPT_THREADS */ - gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); -#endif - - return 0; -} diff --git a/qemu/crypto/ivgen-essiv.c b/qemu/crypto/ivgen-essiv.c deleted file mode 100644 index 634de6333..000000000 --- a/qemu/crypto/ivgen-essiv.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * QEMU Crypto block IV generator - essiv - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qemu/bswap.h" -#include "crypto/ivgen-essiv.h" - -typedef struct QCryptoIVGenESSIV QCryptoIVGenESSIV; -struct QCryptoIVGenESSIV { - QCryptoCipher *cipher; -}; - -static int qcrypto_ivgen_essiv_init(QCryptoIVGen *ivgen, - const uint8_t *key, size_t nkey, - Error **errp) -{ - uint8_t *salt; - size_t nhash; - size_t nsalt; - QCryptoIVGenESSIV *essiv = g_new0(QCryptoIVGenESSIV, 1); - - /* Not necessarily the same as nkey */ - nsalt = qcrypto_cipher_get_key_len(ivgen->cipher); - - nhash = qcrypto_hash_digest_len(ivgen->hash); - /* Salt must be larger of hash size or key size */ - salt = g_new0(uint8_t, MAX(nhash, nsalt)); - - if (qcrypto_hash_bytes(ivgen->hash, (const gchar *)key, nkey, - &salt, &nhash, - errp) < 0) { - g_free(essiv); - return -1; - } - - /* Now potentially truncate salt to match cipher key len */ - essiv->cipher = qcrypto_cipher_new(ivgen->cipher, - QCRYPTO_CIPHER_MODE_ECB, - salt, MIN(nhash, nsalt), - errp); - if (!essiv->cipher) { - g_free(essiv); - g_free(salt); - return -1; - } - - g_free(salt); - ivgen->private = essiv; - - return 0; -} - -static int qcrypto_ivgen_essiv_calculate(QCryptoIVGen *ivgen, - uint64_t sector, - uint8_t *iv, size_t niv, - Error **errp) -{ - QCryptoIVGenESSIV *essiv = ivgen->private; - size_t ndata = qcrypto_cipher_get_block_len(ivgen->cipher); - uint8_t *data = g_new(uint8_t, ndata); - - sector = cpu_to_le64(sector); - memcpy(data, (uint8_t *)§or, ndata); - if (sizeof(sector) < ndata) { - memset(data + sizeof(sector), 0, ndata - sizeof(sector)); - } - - if (qcrypto_cipher_encrypt(essiv->cipher, - data, - data, - ndata, - errp) < 0) { - g_free(data); - return -1; - } - - if (ndata > niv) { - ndata = niv; - } - memcpy(iv, data, ndata); - if (ndata < niv) { - memset(iv + ndata, 0, niv - ndata); - } - g_free(data); - return 0; -} - -static void qcrypto_ivgen_essiv_cleanup(QCryptoIVGen *ivgen) -{ - QCryptoIVGenESSIV *essiv = ivgen->private; - - qcrypto_cipher_free(essiv->cipher); - g_free(essiv); -} - - -struct QCryptoIVGenDriver qcrypto_ivgen_essiv = { - .init = qcrypto_ivgen_essiv_init, - .calculate = qcrypto_ivgen_essiv_calculate, - .cleanup = qcrypto_ivgen_essiv_cleanup, -}; - diff --git a/qemu/crypto/ivgen-essiv.h b/qemu/crypto/ivgen-essiv.h deleted file mode 100644 index 4a00af849..000000000 --- a/qemu/crypto/ivgen-essiv.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QEMU Crypto block IV generator - essiv - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "crypto/ivgenpriv.h" - -#ifndef QCRYPTO_IVGEN_ESSIV_H__ -#define QCRYPTO_IVGEN_ESSIV_H__ - -extern struct QCryptoIVGenDriver qcrypto_ivgen_essiv; - -#endif /* QCRYPTO_IVGEN_ESSIV_H__ */ diff --git a/qemu/crypto/ivgen-plain.c b/qemu/crypto/ivgen-plain.c deleted file mode 100644 index 9b9b4ad0b..000000000 --- a/qemu/crypto/ivgen-plain.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * QEMU Crypto block IV generator - plain - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qemu/bswap.h" -#include "crypto/ivgen-plain.h" - -static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen, - const uint8_t *key, size_t nkey, - Error **errp) -{ - return 0; -} - -static int qcrypto_ivgen_plain_calculate(QCryptoIVGen *ivgen, - uint64_t sector, - uint8_t *iv, size_t niv, - Error **errp) -{ - size_t ivprefix; - uint32_t shortsector = cpu_to_le32((sector & 0xffffffff)); - ivprefix = sizeof(shortsector); - if (ivprefix > niv) { - ivprefix = niv; - } - memcpy(iv, &shortsector, ivprefix); - if (ivprefix < niv) { - memset(iv + ivprefix, 0, niv - ivprefix); - } - return 0; -} - -static void qcrypto_ivgen_plain_cleanup(QCryptoIVGen *ivgen) -{ -} - - -struct QCryptoIVGenDriver qcrypto_ivgen_plain = { - .init = qcrypto_ivgen_plain_init, - .calculate = qcrypto_ivgen_plain_calculate, - .cleanup = qcrypto_ivgen_plain_cleanup, -}; - diff --git a/qemu/crypto/ivgen-plain.h b/qemu/crypto/ivgen-plain.h deleted file mode 100644 index 0fe8835c3..000000000 --- a/qemu/crypto/ivgen-plain.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QEMU Crypto block IV generator - plain - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "crypto/ivgenpriv.h" - -#ifndef QCRYPTO_IVGEN_PLAIN_H__ -#define QCRYPTO_IVGEN_PLAIN_H__ - -extern struct QCryptoIVGenDriver qcrypto_ivgen_plain; - -#endif /* QCRYPTO_IVGEN_PLAIN_H__ */ diff --git a/qemu/crypto/ivgen-plain64.c b/qemu/crypto/ivgen-plain64.c deleted file mode 100644 index 6c6b1b44c..000000000 --- a/qemu/crypto/ivgen-plain64.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * QEMU Crypto block IV generator - plain - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "qemu/bswap.h" -#include "crypto/ivgen-plain.h" - -static int qcrypto_ivgen_plain_init(QCryptoIVGen *ivgen, - const uint8_t *key, size_t nkey, - Error **errp) -{ - return 0; -} - -static int qcrypto_ivgen_plain_calculate(QCryptoIVGen *ivgen, - uint64_t sector, - uint8_t *iv, size_t niv, - Error **errp) -{ - size_t ivprefix; - ivprefix = sizeof(sector); - sector = cpu_to_le64(sector); - if (ivprefix > niv) { - ivprefix = niv; - } - memcpy(iv, §or, ivprefix); - if (ivprefix < niv) { - memset(iv + ivprefix, 0, niv - ivprefix); - } - return 0; -} - -static void qcrypto_ivgen_plain_cleanup(QCryptoIVGen *ivgen) -{ -} - - -struct QCryptoIVGenDriver qcrypto_ivgen_plain64 = { - .init = qcrypto_ivgen_plain_init, - .calculate = qcrypto_ivgen_plain_calculate, - .cleanup = qcrypto_ivgen_plain_cleanup, -}; - diff --git a/qemu/crypto/ivgen-plain64.h b/qemu/crypto/ivgen-plain64.h deleted file mode 100644 index c4104459b..000000000 --- a/qemu/crypto/ivgen-plain64.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * QEMU Crypto block IV generator - plain64 - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "crypto/ivgenpriv.h" - -#ifndef QCRYPTO_IVGEN_PLAIN64_H__ -#define QCRYPTO_IVGEN_PLAIN64_H__ - -extern struct QCryptoIVGenDriver qcrypto_ivgen_plain64; - -#endif /* QCRYPTO_IVGEN_PLAIN64_H__ */ diff --git a/qemu/crypto/ivgen.c b/qemu/crypto/ivgen.c deleted file mode 100644 index f66435112..000000000 --- a/qemu/crypto/ivgen.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * QEMU Crypto block IV generator - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" - -#include "crypto/ivgenpriv.h" -#include "crypto/ivgen-plain.h" -#include "crypto/ivgen-plain64.h" -#include "crypto/ivgen-essiv.h" - - -QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg, - QCryptoCipherAlgorithm cipheralg, - QCryptoHashAlgorithm hash, - const uint8_t *key, size_t nkey, - Error **errp) -{ - QCryptoIVGen *ivgen = g_new0(QCryptoIVGen, 1); - - ivgen->algorithm = alg; - ivgen->cipher = cipheralg; - ivgen->hash = hash; - - switch (alg) { - case QCRYPTO_IVGEN_ALG_PLAIN: - ivgen->driver = &qcrypto_ivgen_plain; - break; - case QCRYPTO_IVGEN_ALG_PLAIN64: - ivgen->driver = &qcrypto_ivgen_plain64; - break; - case QCRYPTO_IVGEN_ALG_ESSIV: - ivgen->driver = &qcrypto_ivgen_essiv; - break; - default: - error_setg(errp, "Unknown block IV generator algorithm %d", alg); - g_free(ivgen); - return NULL; - } - - if (ivgen->driver->init(ivgen, key, nkey, errp) < 0) { - g_free(ivgen); - return NULL; - } - - return ivgen; -} - - -int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen, - uint64_t sector, - uint8_t *iv, size_t niv, - Error **errp) -{ - return ivgen->driver->calculate(ivgen, sector, iv, niv, errp); -} - - -QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen) -{ - return ivgen->algorithm; -} - - -QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen) -{ - return ivgen->cipher; -} - - -QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen) -{ - return ivgen->hash; -} - - -void qcrypto_ivgen_free(QCryptoIVGen *ivgen) -{ - if (!ivgen) { - return; - } - ivgen->driver->cleanup(ivgen); - g_free(ivgen); -} diff --git a/qemu/crypto/ivgenpriv.h b/qemu/crypto/ivgenpriv.h deleted file mode 100644 index 7b87e02ea..000000000 --- a/qemu/crypto/ivgenpriv.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * QEMU Crypto block IV generator - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef QCRYPTO_IVGEN_PRIV_H__ -#define QCRYPTO_IVGEN_PRIV_H__ - -#include "crypto/ivgen.h" - -typedef struct QCryptoIVGenDriver QCryptoIVGenDriver; - -struct QCryptoIVGenDriver { - int (*init)(QCryptoIVGen *ivgen, - const uint8_t *key, size_t nkey, - Error **errp); - int (*calculate)(QCryptoIVGen *ivgen, - uint64_t sector, - uint8_t *iv, size_t niv, - Error **errp); - void (*cleanup)(QCryptoIVGen *ivgen); -}; - -struct QCryptoIVGen { - QCryptoIVGenDriver *driver; - void *private; - - QCryptoIVGenAlgorithm algorithm; - QCryptoCipherAlgorithm cipher; - QCryptoHashAlgorithm hash; -}; - - -#endif /* QCRYPTO_IVGEN_PRIV_H__ */ diff --git a/qemu/crypto/pbkdf-gcrypt.c b/qemu/crypto/pbkdf-gcrypt.c deleted file mode 100644 index 997b311d8..000000000 --- a/qemu/crypto/pbkdf-gcrypt.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * QEMU Crypto PBKDF support (Password-Based Key Derivation Function) - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/pbkdf.h" -#include "gcrypt.h" - -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash) -{ - switch (hash) { - case QCRYPTO_HASH_ALG_MD5: - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA256: - return true; - default: - return false; - } -} - -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, - const uint8_t *key, size_t nkey, - const uint8_t *salt, size_t nsalt, - unsigned int iterations, - uint8_t *out, size_t nout, - Error **errp) -{ - static const int hash_map[QCRYPTO_HASH_ALG__MAX] = { - [QCRYPTO_HASH_ALG_MD5] = GCRY_MD_MD5, - [QCRYPTO_HASH_ALG_SHA1] = GCRY_MD_SHA1, - [QCRYPTO_HASH_ALG_SHA256] = GCRY_MD_SHA256, - }; - int ret; - - if (hash >= G_N_ELEMENTS(hash_map) || - hash_map[hash] == GCRY_MD_NONE) { - error_setg(errp, "Unexpected hash algorithm %d", hash); - return -1; - } - - ret = gcry_kdf_derive(key, nkey, GCRY_KDF_PBKDF2, - hash_map[hash], - salt, nsalt, iterations, - nout, out); - if (ret != 0) { - error_setg(errp, "Cannot derive password: %s", - gcry_strerror(ret)); - return -1; - } - - return 0; -} diff --git a/qemu/crypto/pbkdf-nettle.c b/qemu/crypto/pbkdf-nettle.c deleted file mode 100644 index db9fc1578..000000000 --- a/qemu/crypto/pbkdf-nettle.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * QEMU Crypto PBKDF support (Password-Based Key Derivation Function) - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/pbkdf.h" -#include "nettle/pbkdf2.h" - - -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash) -{ - switch (hash) { - case QCRYPTO_HASH_ALG_SHA1: - case QCRYPTO_HASH_ALG_SHA256: - return true; - default: - return false; - } -} - -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash, - const uint8_t *key, size_t nkey, - const uint8_t *salt, size_t nsalt, - unsigned int iterations, - uint8_t *out, size_t nout, - Error **errp) -{ - switch (hash) { - case QCRYPTO_HASH_ALG_SHA1: - pbkdf2_hmac_sha1(nkey, key, - iterations, - nsalt, salt, - nout, out); - break; - - case QCRYPTO_HASH_ALG_SHA256: - pbkdf2_hmac_sha256(nkey, key, - iterations, - nsalt, salt, - nout, out); - break; - - default: - error_setg_errno(errp, ENOSYS, - "PBKDF does not support hash algorithm %d", hash); - return -1; - } - return 0; -} diff --git a/qemu/crypto/pbkdf-stub.c b/qemu/crypto/pbkdf-stub.c deleted file mode 100644 index 266a5051b..000000000 --- a/qemu/crypto/pbkdf-stub.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * QEMU Crypto PBKDF support (Password-Based Key Derivation Function) - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/pbkdf.h" - -bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash G_GNUC_UNUSED) -{ - return false; -} - -int qcrypto_pbkdf2(QCryptoHashAlgorithm hash G_GNUC_UNUSED, - const uint8_t *key G_GNUC_UNUSED, - size_t nkey G_GNUC_UNUSED, - const uint8_t *salt G_GNUC_UNUSED, - size_t nsalt G_GNUC_UNUSED, - unsigned int iterations G_GNUC_UNUSED, - uint8_t *out G_GNUC_UNUSED, - size_t nout G_GNUC_UNUSED, - Error **errp) -{ - error_setg_errno(errp, ENOSYS, - "No crypto library supporting PBKDF in this build"); - return -1; -} diff --git a/qemu/crypto/pbkdf.c b/qemu/crypto/pbkdf.c deleted file mode 100644 index 695cc35df..000000000 --- a/qemu/crypto/pbkdf.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * QEMU Crypto PBKDF support (Password-Based Key Derivation Function) - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/pbkdf.h" -#ifndef _WIN32 -#include <sys/resource.h> -#endif - - -static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, - Error **errp) -{ -#ifdef _WIN32 - FILETIME creation_time, exit_time, kernel_time, user_time; - ULARGE_INTEGER thread_time; - - if (!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time, - &kernel_time, &user_time)) { - error_setg(errp, "Unable to get thread CPU usage"); - return -1; - } - - thread_time.LowPart = user_time.dwLowDateTime; - thread_time.HighPart = user_time.dwHighDateTime; - - /* QuadPart is units of 100ns and we want ms as unit */ - *val_ms = thread_time.QuadPart / 10000ll; - return 0; -#elif defined(RUSAGE_THREAD) - struct rusage ru; - if (getrusage(RUSAGE_THREAD, &ru) < 0) { - error_setg_errno(errp, errno, "Unable to get thread CPU usage"); - return -1; - } - - *val_ms = ((ru.ru_utime.tv_sec * 1000ll) + - (ru.ru_utime.tv_usec / 1000)); - return 0; -#else - *val_ms = 0; - error_setg(errp, "Unable to calculate thread CPU usage on this platform"); - return -1; -#endif -} - -int qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash, - const uint8_t *key, size_t nkey, - const uint8_t *salt, size_t nsalt, - Error **errp) -{ - uint8_t out[32]; - long long int iterations = (1 << 15); - unsigned long long delta_ms, start_ms, end_ms; - - while (1) { - if (qcrypto_pbkdf2_get_thread_cpu(&start_ms, errp) < 0) { - return -1; - } - if (qcrypto_pbkdf2(hash, - key, nkey, - salt, nsalt, - iterations, - out, sizeof(out), - errp) < 0) { - return -1; - } - if (qcrypto_pbkdf2_get_thread_cpu(&end_ms, errp) < 0) { - return -1; - } - - delta_ms = end_ms - start_ms; - - if (delta_ms > 500) { - break; - } else if (delta_ms < 100) { - iterations = iterations * 10; - } else { - iterations = (iterations * 1000 / delta_ms); - } - } - - iterations = iterations * 1000 / delta_ms; - - if (iterations > INT32_MAX) { - error_setg(errp, "Iterations %lld too large for a 32-bit int", - iterations); - return -1; - } - - return iterations; -} diff --git a/qemu/crypto/random-gcrypt.c b/qemu/crypto/random-gcrypt.c deleted file mode 100644 index 0de9a096d..000000000 --- a/qemu/crypto/random-gcrypt.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * QEMU Crypto random number provider - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" - -#include "crypto/random.h" - -#include <gcrypt.h> - -int qcrypto_random_bytes(uint8_t *buf, - size_t buflen, - Error **errp G_GNUC_UNUSED) -{ - gcry_randomize(buf, buflen, GCRY_STRONG_RANDOM); - return 0; -} diff --git a/qemu/crypto/random-gnutls.c b/qemu/crypto/random-gnutls.c deleted file mode 100644 index 04b45a8f8..000000000 --- a/qemu/crypto/random-gnutls.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * QEMU Crypto random number provider - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" - -#include "crypto/random.h" - -#include <gnutls/gnutls.h> -#include <gnutls/crypto.h> - -int qcrypto_random_bytes(uint8_t *buf, - size_t buflen, - Error **errp) -{ - int ret; - - ret = gnutls_rnd(GNUTLS_RND_RANDOM, buf, buflen); - - if (ret < 0) { - error_setg(errp, "Cannot get random bytes: %s", - gnutls_strerror(ret)); - return -1; - } - - return 0; -} diff --git a/qemu/crypto/random-stub.c b/qemu/crypto/random-stub.c deleted file mode 100644 index 63bbf4147..000000000 --- a/qemu/crypto/random-stub.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * QEMU Crypto random number provider - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" - -#include "crypto/random.h" - -int qcrypto_random_bytes(uint8_t *buf G_GNUC_UNUSED, - size_t buflen G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, "No random byte source provided in this build"); - return -1; -} diff --git a/qemu/crypto/secret.c b/qemu/crypto/secret.c deleted file mode 100644 index 285ab7a63..000000000 --- a/qemu/crypto/secret.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * QEMU crypto secret support - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/secret.h" -#include "crypto/cipher.h" -#include "qapi/error.h" -#include "qom/object_interfaces.h" -#include "qemu/base64.h" -#include "trace.h" - - -static void -qcrypto_secret_load_data(QCryptoSecret *secret, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - char *data = NULL; - size_t length = 0; - GError *gerr = NULL; - - *output = NULL; - *outputlen = 0; - - if (secret->file) { - if (secret->data) { - error_setg(errp, - "'file' and 'data' are mutually exclusive"); - return; - } - if (!g_file_get_contents(secret->file, &data, &length, &gerr)) { - error_setg(errp, - "Unable to read %s: %s", - secret->file, gerr->message); - g_error_free(gerr); - return; - } - *output = (uint8_t *)data; - *outputlen = length; - } else if (secret->data) { - *outputlen = strlen(secret->data); - *output = (uint8_t *)g_strdup(secret->data); - } else { - error_setg(errp, "Either 'file' or 'data' must be provided"); - } -} - - -static void qcrypto_secret_decrypt(QCryptoSecret *secret, - const uint8_t *input, - size_t inputlen, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - uint8_t *key = NULL, *ciphertext = NULL, *iv = NULL; - size_t keylen, ciphertextlen, ivlen; - QCryptoCipher *aes = NULL; - uint8_t *plaintext = NULL; - - *output = NULL; - *outputlen = 0; - - if (qcrypto_secret_lookup(secret->keyid, - &key, &keylen, - errp) < 0) { - goto cleanup; - } - - if (keylen != 32) { - error_setg(errp, "Key should be 32 bytes in length"); - goto cleanup; - } - - if (!secret->iv) { - error_setg(errp, "IV is required to decrypt secret"); - goto cleanup; - } - - iv = qbase64_decode(secret->iv, -1, &ivlen, errp); - if (!iv) { - goto cleanup; - } - if (ivlen != 16) { - error_setg(errp, "IV should be 16 bytes in length not %zu", - ivlen); - goto cleanup; - } - - aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256, - QCRYPTO_CIPHER_MODE_CBC, - key, keylen, - errp); - if (!aes) { - goto cleanup; - } - - if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) { - goto cleanup; - } - - if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) { - ciphertext = qbase64_decode((const gchar*)input, - inputlen, - &ciphertextlen, - errp); - if (!ciphertext) { - goto cleanup; - } - plaintext = g_new0(uint8_t, ciphertextlen + 1); - } else { - ciphertextlen = inputlen; - plaintext = g_new0(uint8_t, inputlen + 1); - } - if (qcrypto_cipher_decrypt(aes, - ciphertext ? ciphertext : input, - plaintext, - ciphertextlen, - errp) < 0) { - plaintext = NULL; - goto cleanup; - } - - if (plaintext[ciphertextlen - 1] > 16 || - plaintext[ciphertextlen - 1] > ciphertextlen) { - error_setg(errp, "Incorrect number of padding bytes (%d) " - "found on decrypted data", - (int)plaintext[ciphertextlen - 1]); - g_free(plaintext); - plaintext = NULL; - goto cleanup; - } - - /* Even though plaintext may contain arbitrary NUL - * ensure it is explicitly NUL terminated. - */ - ciphertextlen -= plaintext[ciphertextlen - 1]; - plaintext[ciphertextlen] = '\0'; - - *output = plaintext; - *outputlen = ciphertextlen; - - cleanup: - g_free(ciphertext); - g_free(iv); - g_free(key); - qcrypto_cipher_free(aes); -} - - -static void qcrypto_secret_decode(const uint8_t *input, - size_t inputlen, - uint8_t **output, - size_t *outputlen, - Error **errp) -{ - *output = qbase64_decode((const gchar*)input, - inputlen, - outputlen, - errp); -} - - -static void -qcrypto_secret_prop_set_loaded(Object *obj, - bool value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - if (value) { - Error *local_err = NULL; - uint8_t *input = NULL; - size_t inputlen = 0; - uint8_t *output = NULL; - size_t outputlen = 0; - - qcrypto_secret_load_data(secret, &input, &inputlen, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - if (secret->keyid) { - qcrypto_secret_decrypt(secret, input, inputlen, - &output, &outputlen, &local_err); - g_free(input); - if (local_err) { - error_propagate(errp, local_err); - return; - } - input = output; - inputlen = outputlen; - } else { - if (secret->format != QCRYPTO_SECRET_FORMAT_RAW) { - qcrypto_secret_decode(input, inputlen, - &output, &outputlen, &local_err); - g_free(input); - if (local_err) { - error_propagate(errp, local_err); - return; - } - input = output; - inputlen = outputlen; - } - } - - secret->rawdata = input; - secret->rawlen = inputlen; - } else { - g_free(secret->rawdata); - secret->rawlen = 0; - } -} - - -static bool -qcrypto_secret_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return secret->data != NULL; -} - - -static void -qcrypto_secret_prop_set_format(Object *obj, - int value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *creds = QCRYPTO_SECRET(obj); - - creds->format = value; -} - - -static int -qcrypto_secret_prop_get_format(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoSecret *creds = QCRYPTO_SECRET(obj); - - return creds->format; -} - - -static void -qcrypto_secret_prop_set_data(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->data); - secret->data = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_data(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->data); -} - - -static void -qcrypto_secret_prop_set_file(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->file); - secret->file = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_file(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->file); -} - - -static void -qcrypto_secret_prop_set_iv(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->iv); - secret->iv = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_iv(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->iv); -} - - -static void -qcrypto_secret_prop_set_keyid(Object *obj, - const char *value, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->keyid); - secret->keyid = g_strdup(value); -} - - -static char * -qcrypto_secret_prop_get_keyid(Object *obj, - Error **errp) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - return g_strdup(secret->keyid); -} - - -static void -qcrypto_secret_complete(UserCreatable *uc, Error **errp) -{ - object_property_set_bool(OBJECT(uc), true, "loaded", errp); -} - - -static void -qcrypto_secret_finalize(Object *obj) -{ - QCryptoSecret *secret = QCRYPTO_SECRET(obj); - - g_free(secret->iv); - g_free(secret->file); - g_free(secret->keyid); - g_free(secret->rawdata); - g_free(secret->data); -} - -static void -qcrypto_secret_class_init(ObjectClass *oc, void *data) -{ - UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); - - ucc->complete = qcrypto_secret_complete; - - object_class_property_add_bool(oc, "loaded", - qcrypto_secret_prop_get_loaded, - qcrypto_secret_prop_set_loaded, - NULL); - object_class_property_add_enum(oc, "format", - "QCryptoSecretFormat", - QCryptoSecretFormat_lookup, - qcrypto_secret_prop_get_format, - qcrypto_secret_prop_set_format, - NULL); - object_class_property_add_str(oc, "data", - qcrypto_secret_prop_get_data, - qcrypto_secret_prop_set_data, - NULL); - object_class_property_add_str(oc, "file", - qcrypto_secret_prop_get_file, - qcrypto_secret_prop_set_file, - NULL); - object_class_property_add_str(oc, "keyid", - qcrypto_secret_prop_get_keyid, - qcrypto_secret_prop_set_keyid, - NULL); - object_class_property_add_str(oc, "iv", - qcrypto_secret_prop_get_iv, - qcrypto_secret_prop_set_iv, - NULL); -} - - -int qcrypto_secret_lookup(const char *secretid, - uint8_t **data, - size_t *datalen, - Error **errp) -{ - Object *obj; - QCryptoSecret *secret; - - obj = object_resolve_path_component( - object_get_objects_root(), secretid); - if (!obj) { - error_setg(errp, "No secret with id '%s'", secretid); - return -1; - } - - secret = (QCryptoSecret *) - object_dynamic_cast(obj, - TYPE_QCRYPTO_SECRET); - if (!secret) { - error_setg(errp, "Object with id '%s' is not a secret", - secretid); - return -1; - } - - if (!secret->rawdata) { - error_setg(errp, "Secret with id '%s' has no data", - secretid); - return -1; - } - - *data = g_new0(uint8_t, secret->rawlen + 1); - memcpy(*data, secret->rawdata, secret->rawlen); - (*data)[secret->rawlen] = '\0'; - *datalen = secret->rawlen; - - return 0; -} - - -char *qcrypto_secret_lookup_as_utf8(const char *secretid, - Error **errp) -{ - uint8_t *data; - size_t datalen; - - if (qcrypto_secret_lookup(secretid, - &data, - &datalen, - errp) < 0) { - return NULL; - } - - if (!g_utf8_validate((const gchar*)data, datalen, NULL)) { - error_setg(errp, - "Data from secret %s is not valid UTF-8", - secretid); - g_free(data); - return NULL; - } - - return (char *)data; -} - - -char *qcrypto_secret_lookup_as_base64(const char *secretid, - Error **errp) -{ - uint8_t *data; - size_t datalen; - char *ret; - - if (qcrypto_secret_lookup(secretid, - &data, - &datalen, - errp) < 0) { - return NULL; - } - - ret = g_base64_encode(data, datalen); - g_free(data); - return ret; -} - - -static const TypeInfo qcrypto_secret_info = { - .parent = TYPE_OBJECT, - .name = TYPE_QCRYPTO_SECRET, - .instance_size = sizeof(QCryptoSecret), - .instance_finalize = qcrypto_secret_finalize, - .class_size = sizeof(QCryptoSecretClass), - .class_init = qcrypto_secret_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } -}; - - -static void -qcrypto_secret_register_types(void) -{ - type_register_static(&qcrypto_secret_info); -} - - -type_init(qcrypto_secret_register_types); diff --git a/qemu/crypto/tlscreds.c b/qemu/crypto/tlscreds.c deleted file mode 100644 index 1620e126a..000000000 --- a/qemu/crypto/tlscreds.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * QEMU crypto TLS credential support - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "crypto/tlscredspriv.h" -#include "trace.h" - -#define DH_BITS 2048 - -#ifdef CONFIG_GNUTLS -int -qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds, - const char *filename, - gnutls_dh_params_t *dh_params, - Error **errp) -{ - int ret; - - trace_qcrypto_tls_creds_load_dh(creds, filename ? filename : "<generated>"); - - if (filename == NULL) { - ret = gnutls_dh_params_init(dh_params); - if (ret < 0) { - error_setg(errp, "Unable to initialize DH parameters: %s", - gnutls_strerror(ret)); - return -1; - } - ret = gnutls_dh_params_generate2(*dh_params, DH_BITS); - if (ret < 0) { - gnutls_dh_params_deinit(*dh_params); - *dh_params = NULL; - error_setg(errp, "Unable to generate DH parameters: %s", - gnutls_strerror(ret)); - return -1; - } - } else { - GError *gerr = NULL; - gchar *contents; - gsize len; - gnutls_datum_t data; - if (!g_file_get_contents(filename, - &contents, - &len, - &gerr)) { - - error_setg(errp, "%s", gerr->message); - g_error_free(gerr); - return -1; - } - data.data = (unsigned char *)contents; - data.size = len; - ret = gnutls_dh_params_init(dh_params); - if (ret < 0) { - g_free(contents); - error_setg(errp, "Unable to initialize DH parameters: %s", - gnutls_strerror(ret)); - return -1; - } - ret = gnutls_dh_params_import_pkcs3(*dh_params, - &data, - GNUTLS_X509_FMT_PEM); - g_free(contents); - if (ret < 0) { - gnutls_dh_params_deinit(*dh_params); - *dh_params = NULL; - error_setg(errp, "Unable to load DH parameters from %s: %s", - filename, gnutls_strerror(ret)); - return -1; - } - } - - return 0; -} - - -int -qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds, - const char *filename, - bool required, - char **cred, - Error **errp) -{ - struct stat sb; - int ret = -1; - - if (!creds->dir) { - if (required) { - error_setg(errp, "Missing 'dir' property value"); - return -1; - } else { - return 0; - } - } - - *cred = g_strdup_printf("%s/%s", creds->dir, filename); - - if (stat(*cred, &sb) < 0) { - if (errno == ENOENT && !required) { - ret = 0; - } else { - error_setg_errno(errp, errno, - "Unable to access credentials %s", - *cred); - } - g_free(*cred); - *cred = NULL; - goto cleanup; - } - - ret = 0; - cleanup: - trace_qcrypto_tls_creds_get_path(creds, filename, - *cred ? *cred : "<none>"); - return ret; -} - - -#endif /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_prop_set_verify(Object *obj, - bool value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - creds->verifyPeer = value; -} - - -static bool -qcrypto_tls_creds_prop_get_verify(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - return creds->verifyPeer; -} - - -static void -qcrypto_tls_creds_prop_set_dir(Object *obj, - const char *value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - creds->dir = g_strdup(value); -} - - -static char * -qcrypto_tls_creds_prop_get_dir(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - return g_strdup(creds->dir); -} - - -static void -qcrypto_tls_creds_prop_set_endpoint(Object *obj, - int value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - creds->endpoint = value; -} - - -static int -qcrypto_tls_creds_prop_get_endpoint(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - return creds->endpoint; -} - - -static void -qcrypto_tls_creds_class_init(ObjectClass *oc, void *data) -{ - object_class_property_add_bool(oc, "verify-peer", - qcrypto_tls_creds_prop_get_verify, - qcrypto_tls_creds_prop_set_verify, - NULL); - object_class_property_add_str(oc, "dir", - qcrypto_tls_creds_prop_get_dir, - qcrypto_tls_creds_prop_set_dir, - NULL); - object_class_property_add_enum(oc, "endpoint", - "QCryptoTLSCredsEndpoint", - QCryptoTLSCredsEndpoint_lookup, - qcrypto_tls_creds_prop_get_endpoint, - qcrypto_tls_creds_prop_set_endpoint, - NULL); -} - - -static void -qcrypto_tls_creds_init(Object *obj) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - creds->verifyPeer = true; -} - - -static void -qcrypto_tls_creds_finalize(Object *obj) -{ - QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj); - - g_free(creds->dir); -} - - -static const TypeInfo qcrypto_tls_creds_info = { - .parent = TYPE_OBJECT, - .name = TYPE_QCRYPTO_TLS_CREDS, - .instance_size = sizeof(QCryptoTLSCreds), - .instance_init = qcrypto_tls_creds_init, - .instance_finalize = qcrypto_tls_creds_finalize, - .class_init = qcrypto_tls_creds_class_init, - .class_size = sizeof(QCryptoTLSCredsClass), - .abstract = true, -}; - - -static void -qcrypto_tls_creds_register_types(void) -{ - type_register_static(&qcrypto_tls_creds_info); -} - - -type_init(qcrypto_tls_creds_register_types); diff --git a/qemu/crypto/tlscredsanon.c b/qemu/crypto/tlscredsanon.c deleted file mode 100644 index 146422008..000000000 --- a/qemu/crypto/tlscredsanon.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * QEMU crypto TLS anonymous credential support - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/tlscredsanon.h" -#include "crypto/tlscredspriv.h" -#include "qapi/error.h" -#include "qom/object_interfaces.h" -#include "trace.h" - - -#ifdef CONFIG_GNUTLS - - -static int -qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds, - Error **errp) -{ - char *dhparams = NULL; - int ret; - int rv = -1; - - trace_qcrypto_tls_creds_anon_load(creds, - creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>"); - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - if (qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_DH_PARAMS, - false, &dhparams, errp) < 0) { - goto cleanup; - } - - ret = gnutls_anon_allocate_server_credentials(&creds->data.server); - if (ret < 0) { - error_setg(errp, "Cannot allocate credentials: %s", - gnutls_strerror(ret)); - goto cleanup; - } - - if (qcrypto_tls_creds_get_dh_params_file(&creds->parent_obj, dhparams, - &creds->parent_obj.dh_params, - errp) < 0) { - goto cleanup; - } - - gnutls_anon_set_server_dh_params(creds->data.server, - creds->parent_obj.dh_params); - } else { - ret = gnutls_anon_allocate_client_credentials(&creds->data.client); - if (ret < 0) { - error_setg(errp, "Cannot allocate credentials: %s", - gnutls_strerror(ret)); - goto cleanup; - } - } - - rv = 0; - cleanup: - g_free(dhparams); - return rv; -} - - -static void -qcrypto_tls_creds_anon_unload(QCryptoTLSCredsAnon *creds) -{ - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) { - if (creds->data.client) { - gnutls_anon_free_client_credentials(creds->data.client); - creds->data.client = NULL; - } - } else { - if (creds->data.server) { - gnutls_anon_free_server_credentials(creds->data.server); - creds->data.server = NULL; - } - } - if (creds->parent_obj.dh_params) { - gnutls_dh_params_deinit(creds->parent_obj.dh_params); - creds->parent_obj.dh_params = NULL; - } -} - -#else /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_anon_load(QCryptoTLSCredsAnon *creds G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, "TLS credentials support requires GNUTLS"); -} - - -static void -qcrypto_tls_creds_anon_unload(QCryptoTLSCredsAnon *creds G_GNUC_UNUSED) -{ - /* nada */ -} - - -#endif /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_anon_prop_set_loaded(Object *obj, - bool value, - Error **errp) -{ - QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj); - - if (value) { - qcrypto_tls_creds_anon_load(creds, errp); - } else { - qcrypto_tls_creds_anon_unload(creds); - } -} - - -#ifdef CONFIG_GNUTLS - - -static bool -qcrypto_tls_creds_anon_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj); - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - return creds->data.server != NULL; - } else { - return creds->data.client != NULL; - } -} - - -#else /* ! CONFIG_GNUTLS */ - - -static bool -qcrypto_tls_creds_anon_prop_get_loaded(Object *obj G_GNUC_UNUSED, - Error **errp G_GNUC_UNUSED) -{ - return false; -} - - -#endif /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_anon_complete(UserCreatable *uc, Error **errp) -{ - object_property_set_bool(OBJECT(uc), true, "loaded", errp); -} - - -static void -qcrypto_tls_creds_anon_finalize(Object *obj) -{ - QCryptoTLSCredsAnon *creds = QCRYPTO_TLS_CREDS_ANON(obj); - - qcrypto_tls_creds_anon_unload(creds); -} - - -static void -qcrypto_tls_creds_anon_class_init(ObjectClass *oc, void *data) -{ - UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); - - ucc->complete = qcrypto_tls_creds_anon_complete; - - object_class_property_add_bool(oc, "loaded", - qcrypto_tls_creds_anon_prop_get_loaded, - qcrypto_tls_creds_anon_prop_set_loaded, - NULL); -} - - -static const TypeInfo qcrypto_tls_creds_anon_info = { - .parent = TYPE_QCRYPTO_TLS_CREDS, - .name = TYPE_QCRYPTO_TLS_CREDS_ANON, - .instance_size = sizeof(QCryptoTLSCredsAnon), - .instance_finalize = qcrypto_tls_creds_anon_finalize, - .class_size = sizeof(QCryptoTLSCredsAnonClass), - .class_init = qcrypto_tls_creds_anon_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } -}; - - -static void -qcrypto_tls_creds_anon_register_types(void) -{ - type_register_static(&qcrypto_tls_creds_anon_info); -} - - -type_init(qcrypto_tls_creds_anon_register_types); diff --git a/qemu/crypto/tlscredspriv.h b/qemu/crypto/tlscredspriv.h deleted file mode 100644 index 9222be4a9..000000000 --- a/qemu/crypto/tlscredspriv.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * QEMU crypto TLS credential support private helpers - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#ifndef QCRYPTO_TLSCRED_PRIV_H__ -#define QCRYPTO_TLSCRED_PRIV_H__ - -#include "crypto/tlscreds.h" - -#ifdef CONFIG_GNUTLS - -int qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds, - const char *filename, - bool required, - char **cred, - Error **errp); - -int qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds, - const char *filename, - gnutls_dh_params_t *dh_params, - Error **errp); - -#endif - -#endif /* QCRYPTO_TLSCRED_PRIV_H__ */ - diff --git a/qemu/crypto/tlscredsx509.c b/qemu/crypto/tlscredsx509.c deleted file mode 100644 index 6a0179c2e..000000000 --- a/qemu/crypto/tlscredsx509.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * QEMU crypto TLS x509 credential support - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/tlscredsx509.h" -#include "crypto/tlscredspriv.h" -#include "crypto/secret.h" -#include "qapi/error.h" -#include "qom/object_interfaces.h" -#include "trace.h" - - -#ifdef CONFIG_GNUTLS - -#include <gnutls/x509.h> - - -static int -qcrypto_tls_creds_check_cert_times(gnutls_x509_crt_t cert, - const char *certFile, - bool isServer, - bool isCA, - Error **errp) -{ - time_t now = time(NULL); - - if (now == ((time_t)-1)) { - error_setg_errno(errp, errno, "cannot get current time"); - return -1; - } - - if (gnutls_x509_crt_get_expiration_time(cert) < now) { - error_setg(errp, - (isCA ? - "The CA certificate %s has expired" : - (isServer ? - "The server certificate %s has expired" : - "The client certificate %s has expired")), - certFile); - return -1; - } - - if (gnutls_x509_crt_get_activation_time(cert) > now) { - error_setg(errp, - (isCA ? - "The CA certificate %s is not yet active" : - (isServer ? - "The server certificate %s is not yet active" : - "The client certificate %s is not yet active")), - certFile); - return -1; - } - - return 0; -} - - -#if LIBGNUTLS_VERSION_NUMBER >= 2 -/* - * The gnutls_x509_crt_get_basic_constraints function isn't - * available in GNUTLS 1.0.x branches. This isn't critical - * though, since gnutls_certificate_verify_peers2 will do - * pretty much the same check at runtime, so we can just - * disable this code - */ -static int -qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds, - gnutls_x509_crt_t cert, - const char *certFile, - bool isServer, - bool isCA, - Error **errp) -{ - int status; - - status = gnutls_x509_crt_get_basic_constraints(cert, NULL, NULL, NULL); - trace_qcrypto_tls_creds_x509_check_basic_constraints( - creds, certFile, status); - - if (status > 0) { /* It is a CA cert */ - if (!isCA) { - error_setg(errp, isServer ? - "The certificate %s basic constraints show a CA, " - "but we need one for a server" : - "The certificate %s basic constraints show a CA, " - "but we need one for a client", - certFile); - return -1; - } - } else if (status == 0) { /* It is not a CA cert */ - if (isCA) { - error_setg(errp, - "The certificate %s basic constraints do not " - "show a CA", - certFile); - return -1; - } - } else if (status == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - /* Missing basicConstraints */ - if (isCA) { - error_setg(errp, - "The certificate %s is missing basic constraints " - "for a CA", - certFile); - return -1; - } - } else { /* General error */ - error_setg(errp, - "Unable to query certificate %s basic constraints: %s", - certFile, gnutls_strerror(status)); - return -1; - } - - return 0; -} -#endif - - -static int -qcrypto_tls_creds_check_cert_key_usage(QCryptoTLSCredsX509 *creds, - gnutls_x509_crt_t cert, - const char *certFile, - bool isCA, - Error **errp) -{ - int status; - unsigned int usage = 0; - unsigned int critical = 0; - - status = gnutls_x509_crt_get_key_usage(cert, &usage, &critical); - trace_qcrypto_tls_creds_x509_check_key_usage( - creds, certFile, status, usage, critical); - - if (status < 0) { - if (status == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - usage = isCA ? GNUTLS_KEY_KEY_CERT_SIGN : - GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_KEY_ENCIPHERMENT; - } else { - error_setg(errp, - "Unable to query certificate %s key usage: %s", - certFile, gnutls_strerror(status)); - return -1; - } - } - - if (isCA) { - if (!(usage & GNUTLS_KEY_KEY_CERT_SIGN)) { - if (critical) { - error_setg(errp, - "Certificate %s usage does not permit " - "certificate signing", certFile); - return -1; - } - } - } else { - if (!(usage & GNUTLS_KEY_DIGITAL_SIGNATURE)) { - if (critical) { - error_setg(errp, - "Certificate %s usage does not permit digital " - "signature", certFile); - return -1; - } - } - if (!(usage & GNUTLS_KEY_KEY_ENCIPHERMENT)) { - if (critical) { - error_setg(errp, - "Certificate %s usage does not permit key " - "encipherment", certFile); - return -1; - } - } - } - - return 0; -} - - -static int -qcrypto_tls_creds_check_cert_key_purpose(QCryptoTLSCredsX509 *creds, - gnutls_x509_crt_t cert, - const char *certFile, - bool isServer, - Error **errp) -{ - int status; - size_t i; - unsigned int purposeCritical; - unsigned int critical; - char *buffer = NULL; - size_t size; - bool allowClient = false, allowServer = false; - - critical = 0; - for (i = 0; ; i++) { - size = 0; - status = gnutls_x509_crt_get_key_purpose_oid(cert, i, buffer, - &size, NULL); - - if (status == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - - /* If there is no data at all, then we must allow - client/server to pass */ - if (i == 0) { - allowServer = allowClient = true; - } - break; - } - if (status != GNUTLS_E_SHORT_MEMORY_BUFFER) { - error_setg(errp, - "Unable to query certificate %s key purpose: %s", - certFile, gnutls_strerror(status)); - return -1; - } - - buffer = g_new0(char, size); - - status = gnutls_x509_crt_get_key_purpose_oid(cert, i, buffer, - &size, &purposeCritical); - - if (status < 0) { - trace_qcrypto_tls_creds_x509_check_key_purpose( - creds, certFile, status, "<none>", purposeCritical); - g_free(buffer); - error_setg(errp, - "Unable to query certificate %s key purpose: %s", - certFile, gnutls_strerror(status)); - return -1; - } - trace_qcrypto_tls_creds_x509_check_key_purpose( - creds, certFile, status, buffer, purposeCritical); - if (purposeCritical) { - critical = true; - } - - if (g_str_equal(buffer, GNUTLS_KP_TLS_WWW_SERVER)) { - allowServer = true; - } else if (g_str_equal(buffer, GNUTLS_KP_TLS_WWW_CLIENT)) { - allowClient = true; - } else if (g_str_equal(buffer, GNUTLS_KP_ANY)) { - allowServer = allowClient = true; - } - - g_free(buffer); - buffer = NULL; - } - - if (isServer) { - if (!allowServer) { - if (critical) { - error_setg(errp, - "Certificate %s purpose does not allow " - "use with a TLS server", certFile); - return -1; - } - } - } else { - if (!allowClient) { - if (critical) { - error_setg(errp, - "Certificate %s purpose does not allow use " - "with a TLS client", certFile); - return -1; - } - } - } - - return 0; -} - - -static int -qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *creds, - gnutls_x509_crt_t cert, - const char *certFile, - bool isServer, - bool isCA, - Error **errp) -{ - if (qcrypto_tls_creds_check_cert_times(cert, certFile, - isServer, isCA, - errp) < 0) { - return -1; - } - -#if LIBGNUTLS_VERSION_NUMBER >= 2 - if (qcrypto_tls_creds_check_cert_basic_constraints(creds, - cert, certFile, - isServer, isCA, - errp) < 0) { - return -1; - } -#endif - - if (qcrypto_tls_creds_check_cert_key_usage(creds, - cert, certFile, - isCA, errp) < 0) { - return -1; - } - - if (!isCA && - qcrypto_tls_creds_check_cert_key_purpose(creds, - cert, certFile, - isServer, errp) < 0) { - return -1; - } - - return 0; -} - - -static int -qcrypto_tls_creds_check_cert_pair(gnutls_x509_crt_t cert, - const char *certFile, - gnutls_x509_crt_t *cacerts, - size_t ncacerts, - const char *cacertFile, - bool isServer, - Error **errp) -{ - unsigned int status; - - if (gnutls_x509_crt_list_verify(&cert, 1, - cacerts, ncacerts, - NULL, 0, - 0, &status) < 0) { - error_setg(errp, isServer ? - "Unable to verify server certificate %s against " - "CA certificate %s" : - "Unable to verify client certificate %s against " - "CA certificate %s", - certFile, cacertFile); - return -1; - } - - if (status != 0) { - const char *reason = "Invalid certificate"; - - if (status & GNUTLS_CERT_INVALID) { - reason = "The certificate is not trusted"; - } - - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { - reason = "The certificate hasn't got a known issuer"; - } - - if (status & GNUTLS_CERT_REVOKED) { - reason = "The certificate has been revoked"; - } - -#ifndef GNUTLS_1_0_COMPAT - if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { - reason = "The certificate uses an insecure algorithm"; - } -#endif - - error_setg(errp, - "Our own certificate %s failed validation against %s: %s", - certFile, cacertFile, reason); - return -1; - } - - return 0; -} - - -static gnutls_x509_crt_t -qcrypto_tls_creds_load_cert(QCryptoTLSCredsX509 *creds, - const char *certFile, - bool isServer, - Error **errp) -{ - gnutls_datum_t data; - gnutls_x509_crt_t cert = NULL; - char *buf = NULL; - gsize buflen; - GError *gerr; - int ret = -1; - - trace_qcrypto_tls_creds_x509_load_cert(creds, isServer, certFile); - - if (gnutls_x509_crt_init(&cert) < 0) { - error_setg(errp, "Unable to initialize certificate"); - goto cleanup; - } - - if (!g_file_get_contents(certFile, &buf, &buflen, &gerr)) { - error_setg(errp, "Cannot load CA cert list %s: %s", - certFile, gerr->message); - g_error_free(gerr); - goto cleanup; - } - - data.data = (unsigned char *)buf; - data.size = strlen(buf); - - if (gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_PEM) < 0) { - error_setg(errp, isServer ? - "Unable to import server certificate %s" : - "Unable to import client certificate %s", - certFile); - goto cleanup; - } - - ret = 0; - - cleanup: - if (ret != 0) { - gnutls_x509_crt_deinit(cert); - cert = NULL; - } - g_free(buf); - return cert; -} - - -static int -qcrypto_tls_creds_load_ca_cert_list(QCryptoTLSCredsX509 *creds, - const char *certFile, - gnutls_x509_crt_t *certs, - unsigned int certMax, - size_t *ncerts, - Error **errp) -{ - gnutls_datum_t data; - char *buf = NULL; - gsize buflen; - int ret = -1; - GError *gerr = NULL; - - *ncerts = 0; - trace_qcrypto_tls_creds_x509_load_cert_list(creds, certFile); - - if (!g_file_get_contents(certFile, &buf, &buflen, &gerr)) { - error_setg(errp, "Cannot load CA cert list %s: %s", - certFile, gerr->message); - g_error_free(gerr); - goto cleanup; - } - - data.data = (unsigned char *)buf; - data.size = strlen(buf); - - if (gnutls_x509_crt_list_import(certs, &certMax, &data, - GNUTLS_X509_FMT_PEM, 0) < 0) { - error_setg(errp, - "Unable to import CA certificate list %s", - certFile); - goto cleanup; - } - *ncerts = certMax; - - ret = 0; - - cleanup: - g_free(buf); - return ret; -} - - -#define MAX_CERTS 16 -static int -qcrypto_tls_creds_x509_sanity_check(QCryptoTLSCredsX509 *creds, - bool isServer, - const char *cacertFile, - const char *certFile, - Error **errp) -{ - gnutls_x509_crt_t cert = NULL; - gnutls_x509_crt_t cacerts[MAX_CERTS]; - size_t ncacerts = 0; - size_t i; - int ret = -1; - - memset(cacerts, 0, sizeof(cacerts)); - if (certFile && - access(certFile, R_OK) == 0) { - cert = qcrypto_tls_creds_load_cert(creds, - certFile, isServer, - errp); - if (!cert) { - goto cleanup; - } - } - if (access(cacertFile, R_OK) == 0) { - if (qcrypto_tls_creds_load_ca_cert_list(creds, - cacertFile, cacerts, - MAX_CERTS, &ncacerts, - errp) < 0) { - goto cleanup; - } - } - - if (cert && - qcrypto_tls_creds_check_cert(creds, - cert, certFile, isServer, - false, errp) < 0) { - goto cleanup; - } - - for (i = 0; i < ncacerts; i++) { - if (qcrypto_tls_creds_check_cert(creds, - cacerts[i], cacertFile, - isServer, true, errp) < 0) { - goto cleanup; - } - } - - if (cert && ncacerts && - qcrypto_tls_creds_check_cert_pair(cert, certFile, cacerts, - ncacerts, cacertFile, - isServer, errp) < 0) { - goto cleanup; - } - - ret = 0; - - cleanup: - if (cert) { - gnutls_x509_crt_deinit(cert); - } - for (i = 0; i < ncacerts; i++) { - gnutls_x509_crt_deinit(cacerts[i]); - } - return ret; -} - - -static int -qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds, - Error **errp) -{ - char *cacert = NULL, *cacrl = NULL, *cert = NULL, - *key = NULL, *dhparams = NULL; - int ret; - int rv = -1; - - trace_qcrypto_tls_creds_x509_load(creds, - creds->parent_obj.dir ? creds->parent_obj.dir : "<nodir>"); - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - if (qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_CA_CERT, - true, &cacert, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_CA_CRL, - false, &cacrl, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_SERVER_CERT, - true, &cert, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_SERVER_KEY, - true, &key, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_DH_PARAMS, - false, &dhparams, errp) < 0) { - goto cleanup; - } - } else { - if (qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_CA_CERT, - true, &cacert, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_CLIENT_CERT, - false, &cert, errp) < 0 || - qcrypto_tls_creds_get_path(&creds->parent_obj, - QCRYPTO_TLS_CREDS_X509_CLIENT_KEY, - false, &key, errp) < 0) { - goto cleanup; - } - } - - if (creds->sanityCheck && - qcrypto_tls_creds_x509_sanity_check(creds, - creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, - cacert, cert, errp) < 0) { - goto cleanup; - } - - ret = gnutls_certificate_allocate_credentials(&creds->data); - if (ret < 0) { - error_setg(errp, "Cannot allocate credentials: '%s'", - gnutls_strerror(ret)); - goto cleanup; - } - - ret = gnutls_certificate_set_x509_trust_file(creds->data, - cacert, - GNUTLS_X509_FMT_PEM); - if (ret < 0) { - error_setg(errp, "Cannot load CA certificate '%s': %s", - cacert, gnutls_strerror(ret)); - goto cleanup; - } - - if (cert != NULL && key != NULL) { -#if GNUTLS_VERSION_NUMBER >= 0x030111 - char *password = NULL; - if (creds->passwordid) { - password = qcrypto_secret_lookup_as_utf8(creds->passwordid, - errp); - if (!password) { - goto cleanup; - } - } - ret = gnutls_certificate_set_x509_key_file2(creds->data, - cert, key, - GNUTLS_X509_FMT_PEM, - password, - 0); - g_free(password); -#else /* GNUTLS_VERSION_NUMBER < 0x030111 */ - if (creds->passwordid) { - error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11"); - goto cleanup; - } - ret = gnutls_certificate_set_x509_key_file(creds->data, - cert, key, - GNUTLS_X509_FMT_PEM); -#endif /* GNUTLS_VERSION_NUMBER < 0x030111 */ - if (ret < 0) { - error_setg(errp, "Cannot load certificate '%s' & key '%s': %s", - cert, key, gnutls_strerror(ret)); - goto cleanup; - } - } - - if (cacrl != NULL) { - ret = gnutls_certificate_set_x509_crl_file(creds->data, - cacrl, - GNUTLS_X509_FMT_PEM); - if (ret < 0) { - error_setg(errp, "Cannot load CRL '%s': %s", - cacrl, gnutls_strerror(ret)); - goto cleanup; - } - } - - if (creds->parent_obj.endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - if (qcrypto_tls_creds_get_dh_params_file(&creds->parent_obj, dhparams, - &creds->parent_obj.dh_params, - errp) < 0) { - goto cleanup; - } - gnutls_certificate_set_dh_params(creds->data, - creds->parent_obj.dh_params); - } - - rv = 0; - cleanup: - g_free(cacert); - g_free(cacrl); - g_free(cert); - g_free(key); - g_free(dhparams); - return rv; -} - - -static void -qcrypto_tls_creds_x509_unload(QCryptoTLSCredsX509 *creds) -{ - if (creds->data) { - gnutls_certificate_free_credentials(creds->data); - creds->data = NULL; - } - if (creds->parent_obj.dh_params) { - gnutls_dh_params_deinit(creds->parent_obj.dh_params); - creds->parent_obj.dh_params = NULL; - } -} - - -#else /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, "TLS credentials support requires GNUTLS"); -} - - -static void -qcrypto_tls_creds_x509_unload(QCryptoTLSCredsX509 *creds G_GNUC_UNUSED) -{ - /* nada */ -} - - -#endif /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_x509_prop_set_loaded(Object *obj, - bool value, - Error **errp) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - if (value) { - qcrypto_tls_creds_x509_load(creds, errp); - } else { - qcrypto_tls_creds_x509_unload(creds); - } -} - - -#ifdef CONFIG_GNUTLS - - -static bool -qcrypto_tls_creds_x509_prop_get_loaded(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - return creds->data != NULL; -} - - -#else /* ! CONFIG_GNUTLS */ - - -static bool -qcrypto_tls_creds_x509_prop_get_loaded(Object *obj G_GNUC_UNUSED, - Error **errp G_GNUC_UNUSED) -{ - return false; -} - - -#endif /* ! CONFIG_GNUTLS */ - - -static void -qcrypto_tls_creds_x509_prop_set_sanity(Object *obj, - bool value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - creds->sanityCheck = value; -} - - -static void -qcrypto_tls_creds_x509_prop_set_passwordid(Object *obj, - const char *value, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - creds->passwordid = g_strdup(value); -} - - -static char * -qcrypto_tls_creds_x509_prop_get_passwordid(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - return g_strdup(creds->passwordid); -} - - -static bool -qcrypto_tls_creds_x509_prop_get_sanity(Object *obj, - Error **errp G_GNUC_UNUSED) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - return creds->sanityCheck; -} - - -static void -qcrypto_tls_creds_x509_complete(UserCreatable *uc, Error **errp) -{ - object_property_set_bool(OBJECT(uc), true, "loaded", errp); -} - - -static void -qcrypto_tls_creds_x509_init(Object *obj) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - creds->sanityCheck = true; -} - - -static void -qcrypto_tls_creds_x509_finalize(Object *obj) -{ - QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); - - g_free(creds->passwordid); - qcrypto_tls_creds_x509_unload(creds); -} - - -static void -qcrypto_tls_creds_x509_class_init(ObjectClass *oc, void *data) -{ - UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); - - ucc->complete = qcrypto_tls_creds_x509_complete; - - object_class_property_add_bool(oc, "loaded", - qcrypto_tls_creds_x509_prop_get_loaded, - qcrypto_tls_creds_x509_prop_set_loaded, - NULL); - object_class_property_add_bool(oc, "sanity-check", - qcrypto_tls_creds_x509_prop_get_sanity, - qcrypto_tls_creds_x509_prop_set_sanity, - NULL); - object_class_property_add_str(oc, "passwordid", - qcrypto_tls_creds_x509_prop_get_passwordid, - qcrypto_tls_creds_x509_prop_set_passwordid, - NULL); -} - - -static const TypeInfo qcrypto_tls_creds_x509_info = { - .parent = TYPE_QCRYPTO_TLS_CREDS, - .name = TYPE_QCRYPTO_TLS_CREDS_X509, - .instance_size = sizeof(QCryptoTLSCredsX509), - .instance_init = qcrypto_tls_creds_x509_init, - .instance_finalize = qcrypto_tls_creds_x509_finalize, - .class_size = sizeof(QCryptoTLSCredsX509Class), - .class_init = qcrypto_tls_creds_x509_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_USER_CREATABLE }, - { } - } -}; - - -static void -qcrypto_tls_creds_x509_register_types(void) -{ - type_register_static(&qcrypto_tls_creds_x509_info); -} - - -type_init(qcrypto_tls_creds_x509_register_types); diff --git a/qemu/crypto/tlssession.c b/qemu/crypto/tlssession.c deleted file mode 100644 index a543e5a57..000000000 --- a/qemu/crypto/tlssession.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * QEMU crypto TLS session support - * - * Copyright (c) 2015 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "qemu/osdep.h" -#include "crypto/tlssession.h" -#include "crypto/tlscredsanon.h" -#include "crypto/tlscredsx509.h" -#include "qapi/error.h" -#include "qemu/acl.h" -#include "trace.h" - -#ifdef CONFIG_GNUTLS - - -#include <gnutls/x509.h> - - -struct QCryptoTLSSession { - QCryptoTLSCreds *creds; - gnutls_session_t handle; - char *hostname; - char *aclname; - bool handshakeComplete; - QCryptoTLSSessionWriteFunc writeFunc; - QCryptoTLSSessionReadFunc readFunc; - void *opaque; - char *peername; -}; - - -void -qcrypto_tls_session_free(QCryptoTLSSession *session) -{ - if (!session) { - return; - } - - gnutls_deinit(session->handle); - g_free(session->hostname); - g_free(session->peername); - g_free(session->aclname); - object_unref(OBJECT(session->creds)); - g_free(session); -} - - -static ssize_t -qcrypto_tls_session_push(void *opaque, const void *buf, size_t len) -{ - QCryptoTLSSession *session = opaque; - - if (!session->writeFunc) { - errno = EIO; - return -1; - }; - - return session->writeFunc(buf, len, session->opaque); -} - - -static ssize_t -qcrypto_tls_session_pull(void *opaque, void *buf, size_t len) -{ - QCryptoTLSSession *session = opaque; - - if (!session->readFunc) { - errno = EIO; - return -1; - }; - - return session->readFunc(buf, len, session->opaque); -} - - -QCryptoTLSSession * -qcrypto_tls_session_new(QCryptoTLSCreds *creds, - const char *hostname, - const char *aclname, - QCryptoTLSCredsEndpoint endpoint, - Error **errp) -{ - QCryptoTLSSession *session; - int ret; - - session = g_new0(QCryptoTLSSession, 1); - trace_qcrypto_tls_session_new( - session, creds, hostname ? hostname : "<none>", - aclname ? aclname : "<none>", endpoint); - - if (hostname) { - session->hostname = g_strdup(hostname); - } - if (aclname) { - session->aclname = g_strdup(aclname); - } - session->creds = creds; - object_ref(OBJECT(creds)); - - if (creds->endpoint != endpoint) { - error_setg(errp, "Credentials endpoint doesn't match session"); - goto error; - } - - if (endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - ret = gnutls_init(&session->handle, GNUTLS_SERVER); - } else { - ret = gnutls_init(&session->handle, GNUTLS_CLIENT); - } - if (ret < 0) { - error_setg(errp, "Cannot initialize TLS session: %s", - gnutls_strerror(ret)); - goto error; - } - - if (object_dynamic_cast(OBJECT(creds), - TYPE_QCRYPTO_TLS_CREDS_ANON)) { - QCryptoTLSCredsAnon *acreds = QCRYPTO_TLS_CREDS_ANON(creds); - - ret = gnutls_priority_set_direct(session->handle, - "NORMAL:+ANON-DH", NULL); - if (ret < 0) { - error_setg(errp, "Unable to set TLS session priority: %s", - gnutls_strerror(ret)); - goto error; - } - if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - ret = gnutls_credentials_set(session->handle, - GNUTLS_CRD_ANON, - acreds->data.server); - } else { - ret = gnutls_credentials_set(session->handle, - GNUTLS_CRD_ANON, - acreds->data.client); - } - if (ret < 0) { - error_setg(errp, "Cannot set session credentials: %s", - gnutls_strerror(ret)); - goto error; - } - } else if (object_dynamic_cast(OBJECT(creds), - TYPE_QCRYPTO_TLS_CREDS_X509)) { - QCryptoTLSCredsX509 *tcreds = QCRYPTO_TLS_CREDS_X509(creds); - - ret = gnutls_set_default_priority(session->handle); - if (ret < 0) { - error_setg(errp, "Cannot set default TLS session priority: %s", - gnutls_strerror(ret)); - goto error; - } - ret = gnutls_credentials_set(session->handle, - GNUTLS_CRD_CERTIFICATE, - tcreds->data); - if (ret < 0) { - error_setg(errp, "Cannot set session credentials: %s", - gnutls_strerror(ret)); - goto error; - } - - if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) { - /* This requests, but does not enforce a client cert. - * The cert checking code later does enforcement */ - gnutls_certificate_server_set_request(session->handle, - GNUTLS_CERT_REQUEST); - } - } else { - error_setg(errp, "Unsupported TLS credentials type %s", - object_get_typename(OBJECT(creds))); - goto error; - } - - gnutls_transport_set_ptr(session->handle, session); - gnutls_transport_set_push_function(session->handle, - qcrypto_tls_session_push); - gnutls_transport_set_pull_function(session->handle, - qcrypto_tls_session_pull); - - return session; - - error: - qcrypto_tls_session_free(session); - return NULL; -} - -static int -qcrypto_tls_session_check_certificate(QCryptoTLSSession *session, - Error **errp) -{ - int ret; - unsigned int status; - const gnutls_datum_t *certs; - unsigned int nCerts, i; - time_t now; - gnutls_x509_crt_t cert = NULL; - - now = time(NULL); - if (now == ((time_t)-1)) { - error_setg_errno(errp, errno, "Cannot get current time"); - return -1; - } - - ret = gnutls_certificate_verify_peers2(session->handle, &status); - if (ret < 0) { - error_setg(errp, "Verify failed: %s", gnutls_strerror(ret)); - return -1; - } - - if (status != 0) { - const char *reason = "Invalid certificate"; - - if (status & GNUTLS_CERT_INVALID) { - reason = "The certificate is not trusted"; - } - - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { - reason = "The certificate hasn't got a known issuer"; - } - - if (status & GNUTLS_CERT_REVOKED) { - reason = "The certificate has been revoked"; - } - - if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { - reason = "The certificate uses an insecure algorithm"; - } - - error_setg(errp, "%s", reason); - return -1; - } - - certs = gnutls_certificate_get_peers(session->handle, &nCerts); - if (!certs) { - error_setg(errp, "No certificate peers"); - return -1; - } - - for (i = 0; i < nCerts; i++) { - ret = gnutls_x509_crt_init(&cert); - if (ret < 0) { - error_setg(errp, "Cannot initialize certificate: %s", - gnutls_strerror(ret)); - return -1; - } - - ret = gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER); - if (ret < 0) { - error_setg(errp, "Cannot import certificate: %s", - gnutls_strerror(ret)); - goto error; - } - - if (gnutls_x509_crt_get_expiration_time(cert) < now) { - error_setg(errp, "The certificate has expired"); - goto error; - } - - if (gnutls_x509_crt_get_activation_time(cert) > now) { - error_setg(errp, "The certificate is not yet activated"); - goto error; - } - - if (gnutls_x509_crt_get_activation_time(cert) > now) { - error_setg(errp, "The certificate is not yet activated"); - goto error; - } - - if (i == 0) { - size_t dnameSize = 1024; - session->peername = g_malloc(dnameSize); - requery: - ret = gnutls_x509_crt_get_dn(cert, session->peername, &dnameSize); - if (ret < 0) { - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { - session->peername = g_realloc(session->peername, - dnameSize); - goto requery; - } - error_setg(errp, "Cannot get client distinguished name: %s", - gnutls_strerror(ret)); - goto error; - } - if (session->aclname) { - qemu_acl *acl = qemu_acl_find(session->aclname); - int allow; - if (!acl) { - error_setg(errp, "Cannot find ACL %s", - session->aclname); - goto error; - } - - allow = qemu_acl_party_is_allowed(acl, session->peername); - - if (!allow) { - error_setg(errp, "TLS x509 ACL check for %s is denied", - session->peername); - goto error; - } - } - if (session->hostname) { - if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) { - error_setg(errp, - "Certificate does not match the hostname %s", - session->hostname); - goto error; - } - } - } - - gnutls_x509_crt_deinit(cert); - } - - return 0; - - error: - gnutls_x509_crt_deinit(cert); - return -1; -} - - -int -qcrypto_tls_session_check_credentials(QCryptoTLSSession *session, - Error **errp) -{ - if (object_dynamic_cast(OBJECT(session->creds), - TYPE_QCRYPTO_TLS_CREDS_ANON)) { - return 0; - } else if (object_dynamic_cast(OBJECT(session->creds), - TYPE_QCRYPTO_TLS_CREDS_X509)) { - if (session->creds->verifyPeer) { - return qcrypto_tls_session_check_certificate(session, - errp); - } else { - return 0; - } - } else { - error_setg(errp, "Unexpected credential type %s", - object_get_typename(OBJECT(session->creds))); - return -1; - } -} - - -void -qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session, - QCryptoTLSSessionWriteFunc writeFunc, - QCryptoTLSSessionReadFunc readFunc, - void *opaque) -{ - session->writeFunc = writeFunc; - session->readFunc = readFunc; - session->opaque = opaque; -} - - -ssize_t -qcrypto_tls_session_write(QCryptoTLSSession *session, - const char *buf, - size_t len) -{ - ssize_t ret = gnutls_record_send(session->handle, buf, len); - - if (ret < 0) { - switch (ret) { - case GNUTLS_E_AGAIN: - errno = EAGAIN; - break; - case GNUTLS_E_INTERRUPTED: - errno = EINTR; - break; - default: - errno = EIO; - break; - } - ret = -1; - } - - return ret; -} - - -ssize_t -qcrypto_tls_session_read(QCryptoTLSSession *session, - char *buf, - size_t len) -{ - ssize_t ret = gnutls_record_recv(session->handle, buf, len); - - if (ret < 0) { - switch (ret) { - case GNUTLS_E_AGAIN: - errno = EAGAIN; - break; - case GNUTLS_E_INTERRUPTED: - errno = EINTR; - break; - default: - errno = EIO; - break; - } - ret = -1; - } - - return ret; -} - - -int -qcrypto_tls_session_handshake(QCryptoTLSSession *session, - Error **errp) -{ - int ret = gnutls_handshake(session->handle); - if (ret == 0) { - session->handshakeComplete = true; - } else { - if (ret == GNUTLS_E_INTERRUPTED || - ret == GNUTLS_E_AGAIN) { - ret = 1; - } else { - error_setg(errp, "TLS handshake failed: %s", - gnutls_strerror(ret)); - ret = -1; - } - } - - return ret; -} - - -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session) -{ - if (session->handshakeComplete) { - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; - } else if (gnutls_record_get_direction(session->handle) == 0) { - return QCRYPTO_TLS_HANDSHAKE_RECVING; - } else { - return QCRYPTO_TLS_HANDSHAKE_SENDING; - } -} - - -int -qcrypto_tls_session_get_key_size(QCryptoTLSSession *session, - Error **errp) -{ - gnutls_cipher_algorithm_t cipher; - int ssf; - - cipher = gnutls_cipher_get(session->handle); - ssf = gnutls_cipher_get_key_size(cipher); - if (!ssf) { - error_setg(errp, "Cannot get TLS cipher key size"); - return -1; - } - return ssf; -} - - -char * -qcrypto_tls_session_get_peer_name(QCryptoTLSSession *session) -{ - if (session->peername) { - return g_strdup(session->peername); - } - return NULL; -} - - -#else /* ! CONFIG_GNUTLS */ - - -QCryptoTLSSession * -qcrypto_tls_session_new(QCryptoTLSCreds *creds G_GNUC_UNUSED, - const char *hostname G_GNUC_UNUSED, - const char *aclname G_GNUC_UNUSED, - QCryptoTLSCredsEndpoint endpoint G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, "TLS requires GNUTLS support"); - return NULL; -} - - -void -qcrypto_tls_session_free(QCryptoTLSSession *sess G_GNUC_UNUSED) -{ -} - - -int -qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess G_GNUC_UNUSED, - Error **errp) -{ - error_setg(errp, "TLS requires GNUTLS support"); - return -1; -} - - -void -qcrypto_tls_session_set_callbacks( - QCryptoTLSSession *sess G_GNUC_UNUSED, - QCryptoTLSSessionWriteFunc writeFunc G_GNUC_UNUSED, - QCryptoTLSSessionReadFunc readFunc G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED) -{ -} - - -ssize_t -qcrypto_tls_session_write(QCryptoTLSSession *sess, - const char *buf, - size_t len) -{ - errno = -EIO; - return -1; -} - - -ssize_t -qcrypto_tls_session_read(QCryptoTLSSession *sess, - char *buf, - size_t len) -{ - errno = -EIO; - return -1; -} - - -int -qcrypto_tls_session_handshake(QCryptoTLSSession *sess, - Error **errp) -{ - error_setg(errp, "TLS requires GNUTLS support"); - return -1; -} - - -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess) -{ - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; -} - - -int -qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess, - Error **errp) -{ - error_setg(errp, "TLS requires GNUTLS support"); - return -1; -} - - -char * -qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess) -{ - return NULL; -} - -#endif diff --git a/qemu/crypto/xts.c b/qemu/crypto/xts.c deleted file mode 100644 index 95212341f..000000000 --- a/qemu/crypto/xts.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * QEMU Crypto XTS cipher mode - * - * Copyright (c) 2015-2016 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * This code is originally derived from public domain / WTFPL code in - * LibTomCrypt crytographic library http://libtom.org. The XTS code - * was donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) - * to the LibTom Projects - * - */ - -#include "qemu/osdep.h" -#include "crypto/xts.h" - -static void xts_mult_x(uint8_t *I) -{ - int x; - uint8_t t, tt; - - for (x = t = 0; x < 16; x++) { - tt = I[x] >> 7; - I[x] = ((I[x] << 1) | t) & 0xFF; - t = tt; - } - if (tt) { - I[0] ^= 0x87; - } -} - - -/** - * xts_tweak_uncrypt: - * @param ctxt: the cipher context - * @param func: the cipher function - * @src: buffer providing the cipher text of XTS_BLOCK_SIZE bytes - * @dst: buffer to output the plain text of XTS_BLOCK_SIZE bytes - * @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes - * - * Decrypt data with a tweak - */ -static void xts_tweak_decrypt(const void *ctx, - xts_cipher_func *func, - const uint8_t *src, - uint8_t *dst, - uint8_t *iv) -{ - unsigned long x; - - /* tweak encrypt block i */ - for (x = 0; x < XTS_BLOCK_SIZE; x++) { - dst[x] = src[x] ^ iv[x]; - } - - func(ctx, XTS_BLOCK_SIZE, dst, dst); - - for (x = 0; x < XTS_BLOCK_SIZE; x++) { - dst[x] = dst[x] ^ iv[x]; - } - - /* LFSR the tweak */ - xts_mult_x(iv); -} - - -void xts_decrypt(const void *datactx, - const void *tweakctx, - xts_cipher_func *encfunc, - xts_cipher_func *decfunc, - uint8_t *iv, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE]; - unsigned long i, m, mo, lim; - - /* get number of blocks */ - m = length >> 4; - mo = length & 15; - - /* must have at least one full block */ - g_assert(m != 0); - - if (mo == 0) { - lim = m; - } else { - lim = m - 1; - } - - /* encrypt the iv */ - encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); - - for (i = 0; i < lim; i++) { - xts_tweak_decrypt(datactx, decfunc, src, dst, T); - - src += XTS_BLOCK_SIZE; - dst += XTS_BLOCK_SIZE; - } - - /* if length is not a multiple of XTS_BLOCK_SIZE then */ - if (mo > 0) { - memcpy(CC, T, XTS_BLOCK_SIZE); - xts_mult_x(CC); - - /* PP = tweak decrypt block m-1 */ - xts_tweak_decrypt(datactx, decfunc, src, PP, CC); - - /* Pm = first length % XTS_BLOCK_SIZE bytes of PP */ - for (i = 0; i < mo; i++) { - CC[i] = src[XTS_BLOCK_SIZE + i]; - dst[XTS_BLOCK_SIZE + i] = PP[i]; - } - for (; i < XTS_BLOCK_SIZE; i++) { - CC[i] = PP[i]; - } - - /* Pm-1 = Tweak uncrypt CC */ - xts_tweak_decrypt(datactx, decfunc, CC, dst, T); - } - - /* Decrypt the iv back */ - decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T); -} - - -/** - * xts_tweak_crypt: - * @param ctxt: the cipher context - * @param func: the cipher function - * @src: buffer providing the plain text of XTS_BLOCK_SIZE bytes - * @dst: buffer to output the cipher text of XTS_BLOCK_SIZE bytes - * @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes - * - * Encrypt data with a tweak - */ -static void xts_tweak_encrypt(const void *ctx, - xts_cipher_func *func, - const uint8_t *src, - uint8_t *dst, - uint8_t *iv) -{ - unsigned long x; - - /* tweak encrypt block i */ - for (x = 0; x < XTS_BLOCK_SIZE; x++) { - dst[x] = src[x] ^ iv[x]; - } - - func(ctx, XTS_BLOCK_SIZE, dst, dst); - - for (x = 0; x < XTS_BLOCK_SIZE; x++) { - dst[x] = dst[x] ^ iv[x]; - } - - /* LFSR the tweak */ - xts_mult_x(iv); -} - - -void xts_encrypt(const void *datactx, - const void *tweakctx, - xts_cipher_func *encfunc, - xts_cipher_func *decfunc, - uint8_t *iv, - size_t length, - uint8_t *dst, - const uint8_t *src) -{ - uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE]; - unsigned long i, m, mo, lim; - - /* get number of blocks */ - m = length >> 4; - mo = length & 15; - - /* must have at least one full block */ - g_assert(m != 0); - - if (mo == 0) { - lim = m; - } else { - lim = m - 1; - } - - /* encrypt the iv */ - encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); - - for (i = 0; i < lim; i++) { - xts_tweak_encrypt(datactx, encfunc, src, dst, T); - - dst += XTS_BLOCK_SIZE; - src += XTS_BLOCK_SIZE; - } - - /* if length is not a multiple of XTS_BLOCK_SIZE then */ - if (mo > 0) { - /* CC = tweak encrypt block m-1 */ - xts_tweak_encrypt(datactx, encfunc, src, CC, T); - - /* Cm = first length % XTS_BLOCK_SIZE bytes of CC */ - for (i = 0; i < mo; i++) { - PP[i] = src[XTS_BLOCK_SIZE + i]; - dst[XTS_BLOCK_SIZE + i] = CC[i]; - } - - for (; i < XTS_BLOCK_SIZE; i++) { - PP[i] = CC[i]; - } - - /* Cm-1 = Tweak encrypt PP */ - xts_tweak_encrypt(datactx, encfunc, PP, dst, T); - } - - /* Decrypt the iv back */ - decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T); -} |