| 1 | /* |
| 2 | * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. |
| 3 | * |
| 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
| 5 | * this file except in compliance with the License. You can obtain a copy |
| 6 | * in the file LICENSE in the source distribution or at |
| 7 | * https://www.openssl.org/source/license.html |
| 8 | */ |
| 9 | |
| 10 | #include "cipher_aes_xts.h" |
| 11 | |
| 12 | #define XTS_SET_KEY_FN(fn_set_enc_key, fn_set_dec_key, \ |
| 13 | fn_block_enc, fn_block_dec, \ |
| 14 | fn_stream_enc, fn_stream_dec) { \ |
| 15 | size_t bytes = keylen / 2; \ |
| 16 | size_t bits = bytes * 8; \ |
| 17 | \ |
| 18 | if (ctx->enc) { \ |
| 19 | fn_set_enc_key(key, bits, &xctx->ks1.ks); \ |
| 20 | xctx->xts.block1 = (block128_f)fn_block_enc; \ |
| 21 | } else { \ |
| 22 | fn_set_dec_key(key, bits, &xctx->ks1.ks); \ |
| 23 | xctx->xts.block1 = (block128_f)fn_block_dec; \ |
| 24 | } \ |
| 25 | fn_set_enc_key(key + bytes, bits, &xctx->ks2.ks); \ |
| 26 | xctx->xts.block2 = (block128_f)fn_block_enc; \ |
| 27 | xctx->xts.key1 = &xctx->ks1; \ |
| 28 | xctx->xts.key2 = &xctx->ks2; \ |
| 29 | xctx->stream = ctx->enc ? fn_stream_enc : fn_stream_dec; \ |
| 30 | } |
| 31 | |
| 32 | static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx, |
| 33 | const unsigned char *key, |
| 34 | size_t keylen) |
| 35 | { |
| 36 | PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; |
| 37 | OSSL_xts_stream_fn stream_enc = NULL; |
| 38 | OSSL_xts_stream_fn stream_dec = NULL; |
| 39 | |
| 40 | #ifdef AES_XTS_ASM |
| 41 | stream_enc = AES_xts_encrypt; |
| 42 | stream_dec = AES_xts_decrypt; |
| 43 | #endif /* AES_XTS_ASM */ |
| 44 | |
| 45 | #ifdef HWAES_CAPABLE |
| 46 | if (HWAES_CAPABLE) { |
| 47 | # ifdef HWAES_xts_encrypt |
| 48 | stream_enc = HWAES_xts_encrypt; |
| 49 | # endif /* HWAES_xts_encrypt */ |
| 50 | # ifdef HWAES_xts_decrypt |
| 51 | stream_dec = HWAES_xts_decrypt; |
| 52 | # endif /* HWAES_xts_decrypt */ |
| 53 | XTS_SET_KEY_FN(HWAES_set_encrypt_key, HWAES_set_decrypt_key, |
| 54 | HWAES_encrypt, HWAES_decrypt, |
| 55 | stream_enc, stream_dec); |
| 56 | } else |
| 57 | #endif /* HWAES_CAPABLE */ |
| 58 | |
| 59 | #ifdef BSAES_CAPABLE |
| 60 | if (BSAES_CAPABLE) { |
| 61 | stream_enc = bsaes_xts_encrypt; |
| 62 | stream_dec = bsaes_xts_decrypt; |
| 63 | } |
| 64 | #endif /* BSAES_CAPABLE */ |
| 65 | |
| 66 | #ifdef VPAES_CAPABLE |
| 67 | if (VPAES_CAPABLE) { |
| 68 | XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key, |
| 69 | vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec); |
| 70 | } else |
| 71 | #endif /* VPAES_CAPABLE */ |
| 72 | { |
| 73 | XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key, |
| 74 | AES_encrypt, AES_decrypt, stream_enc, stream_dec); |
| 75 | } |
| 76 | return 1; |
| 77 | } |
| 78 | |
| 79 | static void cipher_hw_aes_xts_copyctx(PROV_CIPHER_CTX *dst, |
| 80 | const PROV_CIPHER_CTX *src) |
| 81 | { |
| 82 | PROV_AES_XTS_CTX *sctx = (PROV_AES_XTS_CTX *)src; |
| 83 | PROV_AES_XTS_CTX *dctx = (PROV_AES_XTS_CTX *)dst; |
| 84 | |
| 85 | *dctx = *sctx; |
| 86 | dctx->xts.key1 = &dctx->ks1.ks; |
| 87 | dctx->xts.key2 = &dctx->ks2.ks; |
| 88 | } |
| 89 | |
| 90 | #if defined(AESNI_CAPABLE) |
| 91 | |
| 92 | static int cipher_hw_aesni_xts_initkey(PROV_CIPHER_CTX *ctx, |
| 93 | const unsigned char *key, size_t keylen) |
| 94 | { |
| 95 | PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; |
| 96 | |
| 97 | XTS_SET_KEY_FN(aesni_set_encrypt_key, aesni_set_decrypt_key, |
| 98 | aesni_encrypt, aesni_decrypt, |
| 99 | aesni_xts_encrypt, aesni_xts_decrypt); |
| 100 | return 1; |
| 101 | } |
| 102 | |
| 103 | # define PROV_CIPHER_HW_declare_xts() \ |
| 104 | static const PROV_CIPHER_HW aesni_xts = { \ |
| 105 | cipher_hw_aesni_xts_initkey, \ |
| 106 | NULL, \ |
| 107 | cipher_hw_aes_xts_copyctx \ |
| 108 | }; |
| 109 | # define PROV_CIPHER_HW_select_xts() \ |
| 110 | if (AESNI_CAPABLE) \ |
| 111 | return &aesni_xts; |
| 112 | |
| 113 | # elif defined(SPARC_AES_CAPABLE) |
| 114 | |
| 115 | static int cipher_hw_aes_xts_t4_initkey(PROV_CIPHER_CTX *ctx, |
| 116 | const unsigned char *key, size_t keylen) |
| 117 | { |
| 118 | PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)ctx; |
| 119 | OSSL_xts_stream_fn stream_enc = NULL; |
| 120 | OSSL_xts_stream_fn stream_dec = NULL; |
| 121 | |
| 122 | /* Note: keylen is the size of 2 keys */ |
| 123 | switch (keylen) { |
| 124 | case 32: |
| 125 | stream_enc = aes128_t4_xts_encrypt; |
| 126 | stream_dec = aes128_t4_xts_decrypt; |
| 127 | break; |
| 128 | case 64: |
| 129 | stream_enc = aes256_t4_xts_encrypt; |
| 130 | stream_dec = aes256_t4_xts_decrypt; |
| 131 | break; |
| 132 | default: |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | XTS_SET_KEY_FN(aes_t4_set_encrypt_key, aes_t4_set_decrypt_key, |
| 137 | aes_t4_encrypt, aes_t4_decrypt, |
| 138 | stream_enc, stream_dec); |
| 139 | return 1; |
| 140 | } |
| 141 | |
| 142 | # define PROV_CIPHER_HW_declare_xts() \ |
| 143 | static const PROV_CIPHER_HW aes_xts_t4 = { \ |
| 144 | cipher_hw_aes_xts_t4_initkey, \ |
| 145 | NULL, \ |
| 146 | cipher_hw_aes_xts_copyctx \ |
| 147 | }; |
| 148 | # define PROV_CIPHER_HW_select_xts() \ |
| 149 | if (SPARC_AES_CAPABLE) \ |
| 150 | return &aes_xts_t4; |
| 151 | # else |
| 152 | /* The generic case */ |
| 153 | # define PROV_CIPHER_HW_declare_xts() |
| 154 | # define PROV_CIPHER_HW_select_xts() |
| 155 | #endif |
| 156 | |
| 157 | static const PROV_CIPHER_HW aes_generic_xts = { |
| 158 | cipher_hw_aes_xts_generic_initkey, |
| 159 | NULL, |
| 160 | cipher_hw_aes_xts_copyctx |
| 161 | }; |
| 162 | PROV_CIPHER_HW_declare_xts() |
| 163 | const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits) |
| 164 | { |
| 165 | PROV_CIPHER_HW_select_xts() |
| 166 | return &aes_generic_xts; |
| 167 | } |
| 168 | |