Home | History | Annotate | Download | only in aes
      1 /* Copyright (c) 2017, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #ifndef OPENSSL_HEADER_AES_INTERNAL_H
     16 #define OPENSSL_HEADER_AES_INTERNAL_H
     17 
     18 #include <stdlib.h>
     19 
     20 #include <openssl/cpu.h>
     21 
     22 #if defined(__cplusplus)
     23 extern "C" {
     24 #endif
     25 
     26 
     27 #if !defined(OPENSSL_NO_ASM)
     28 
     29 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
     30 #define HWAES
     31 #define HWAES_ECB
     32 
     33 OPENSSL_INLINE int hwaes_capable(void) {
     34   return (OPENSSL_ia32cap_get()[1] & (1 << (57 - 32))) != 0;
     35 }
     36 
     37 #define VPAES
     38 #if defined(OPENSSL_X86_64)
     39 #define VPAES_CTR32
     40 #endif
     41 OPENSSL_INLINE int vpaes_capable(void) {
     42   return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0;
     43 }
     44 
     45 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
     46 #define HWAES
     47 
     48 OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); }
     49 
     50 #if defined(OPENSSL_ARM)
     51 #define BSAES
     52 OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); }
     53 #endif
     54 
     55 #if defined(OPENSSL_AARCH64)
     56 #define VPAES
     57 #define VPAES_CTR32
     58 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
     59 #endif
     60 
     61 #elif defined(OPENSSL_PPC64LE)
     62 #define HWAES
     63 
     64 OPENSSL_INLINE int hwaes_capable(void) {
     65   return CRYPTO_is_PPC64LE_vcrypto_capable();
     66 }
     67 #endif
     68 
     69 #endif  // !NO_ASM
     70 
     71 
     72 #if defined(HWAES)
     73 
     74 int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
     75                            AES_KEY *key);
     76 int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
     77                            AES_KEY *key);
     78 void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
     79 void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
     80 void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
     81                         const AES_KEY *key, uint8_t *ivec, const int enc);
     82 void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
     83                                  const AES_KEY *key, const uint8_t ivec[16]);
     84 
     85 #else
     86 
     87 // If HWAES isn't defined then we provide dummy functions for each of the hwaes
     88 // functions.
     89 OPENSSL_INLINE int hwaes_capable(void) { return 0; }
     90 
     91 OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
     92                                           AES_KEY *key) {
     93   abort();
     94 }
     95 
     96 OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
     97                                           AES_KEY *key) {
     98   abort();
     99 }
    100 
    101 OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
    102                                    const AES_KEY *key) {
    103   abort();
    104 }
    105 
    106 OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
    107                                    const AES_KEY *key) {
    108   abort();
    109 }
    110 
    111 OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out,
    112                                        size_t length, const AES_KEY *key,
    113                                        uint8_t *ivec, int enc) {
    114   abort();
    115 }
    116 
    117 OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
    118                                                 size_t len, const AES_KEY *key,
    119                                                 const uint8_t ivec[16]) {
    120   abort();
    121 }
    122 
    123 #endif  // !HWAES
    124 
    125 
    126 #if defined(HWAES_ECB)
    127 void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
    128                         const AES_KEY *key, const int enc);
    129 #endif  // HWAES_ECB
    130 
    131 
    132 #if defined(BSAES)
    133 // On platforms where BSAES gets defined (just above), then these functions are
    134 // provided by asm. Note |bsaes_cbc_encrypt| requires |enc| to be zero.
    135 void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
    136                        const AES_KEY *key, uint8_t ivec[16], int enc);
    137 void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
    138                                 const AES_KEY *key, const uint8_t ivec[16]);
    139 #else
    140 OPENSSL_INLINE char bsaes_capable(void) { return 0; }
    141 
    142 // On other platforms, bsaes_capable() will always return false and so the
    143 // following will never be called.
    144 OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
    145                                       size_t length, const AES_KEY *key,
    146                                       uint8_t ivec[16], int enc) {
    147   abort();
    148 }
    149 
    150 OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
    151                                                size_t len, const AES_KEY *key,
    152                                                const uint8_t ivec[16]) {
    153   abort();
    154 }
    155 #endif  // !BSAES
    156 
    157 
    158 #if defined(VPAES)
    159 // On platforms where VPAES gets defined (just above), then these functions are
    160 // provided by asm.
    161 int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
    162 int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
    163 
    164 void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
    165 void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
    166 
    167 void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
    168                        const AES_KEY *key, uint8_t *ivec, int enc);
    169 #if defined(VPAES_CTR32)
    170 void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
    171                                 const AES_KEY *key, const uint8_t ivec[16]);
    172 #endif
    173 #else
    174 OPENSSL_INLINE char vpaes_capable(void) { return 0; }
    175 
    176 // On other platforms, vpaes_capable() will always return false and so the
    177 // following will never be called.
    178 OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
    179                                          AES_KEY *key) {
    180   abort();
    181 }
    182 OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
    183                                          AES_KEY *key) {
    184   abort();
    185 }
    186 OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out,
    187                                   const AES_KEY *key) {
    188   abort();
    189 }
    190 OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out,
    191                                   const AES_KEY *key) {
    192   abort();
    193 }
    194 OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
    195                                       size_t length, const AES_KEY *key,
    196                                       uint8_t *ivec, int enc) {
    197   abort();
    198 }
    199 #endif  // !VPAES
    200 
    201 
    202 void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
    203 void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
    204 int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
    205                              AES_KEY *aeskey);
    206 int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
    207                              AES_KEY *aeskey);
    208 
    209 #if !defined(OPENSSL_NO_ASM) && \
    210     (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
    211 #define AES_NOHW_CBC
    212 void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
    213                           const AES_KEY *key, uint8_t *ivec, const int enc);
    214 #endif
    215 
    216 
    217 #if defined(__cplusplus)
    218 }  // extern C
    219 #endif
    220 
    221 #endif  // OPENSSL_HEADER_AES_INTERNAL_H
    222