1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023 Raptor Engineering, LLC 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/libkern.h> 29 #include <sys/malloc.h> 30 31 #include <machine/cpu.h> 32 33 #include <crypto/openssl/ossl.h> 34 #include <crypto/openssl/ossl_cipher.h> 35 #include <crypto/openssl/ossl_ppc.h> 36 37 unsigned int OPENSSL_ppccap_P = 0; 38 39 ossl_cipher_setkey_t aes_p8_set_encrypt_key; 40 ossl_cipher_setkey_t aes_p8_set_decrypt_key; 41 42 ossl_cipher_setkey_t vpaes_set_encrypt_key; 43 ossl_cipher_setkey_t vpaes_set_decrypt_key; 44 45 ossl_cipher_setkey_t ossl_aes_gcm_setkey; 46 47 void 48 ossl_cpuid(struct ossl_softc *sc) 49 { 50 if (cpu_features2 & PPC_FEATURE2_HAS_VEC_CRYPTO) { 51 OPENSSL_ppccap_P |= PPC_CRYPTO207; 52 } 53 54 if (cpu_features2 & PPC_FEATURE2_ARCH_3_00) { 55 OPENSSL_ppccap_P |= PPC_MADD300; 56 } 57 58 if (cpu_features & PPC_FEATURE_64) { 59 OPENSSL_ppccap_P |= PPC_MFTB; 60 } else { 61 OPENSSL_ppccap_P |= PPC_MFSPR268; 62 } 63 64 if (cpu_features & PPC_FEATURE_HAS_FPU) { 65 OPENSSL_ppccap_P |= PPC_FPU; 66 67 if (cpu_features & PPC_FEATURE_64) { 68 OPENSSL_ppccap_P |= PPC_FPU64; 69 } 70 } 71 72 if (cpu_features & PPC_FEATURE_HAS_ALTIVEC) { 73 OPENSSL_ppccap_P |= PPC_ALTIVEC; 74 } 75 76 /* Pick P8 crypto if available, otherwise fall back to altivec */ 77 if (OPENSSL_ppccap_P & PPC_CRYPTO207) { 78 ossl_cipher_aes_cbc.set_encrypt_key = aes_p8_set_encrypt_key; 79 ossl_cipher_aes_cbc.set_decrypt_key = aes_p8_set_decrypt_key; 80 sc->has_aes = true; 81 82 ossl_cipher_aes_gcm.set_encrypt_key = ossl_aes_gcm_setkey; 83 ossl_cipher_aes_gcm.set_decrypt_key = ossl_aes_gcm_setkey; 84 sc->has_aes_gcm = true; 85 } else if (OPENSSL_ppccap_P & PPC_ALTIVEC) { 86 ossl_cipher_aes_cbc.set_encrypt_key = vpaes_set_encrypt_key; 87 ossl_cipher_aes_cbc.set_decrypt_key = vpaes_set_decrypt_key; 88 sc->has_aes = true; 89 } 90 } 91 92 /* 93 * The following trivial wrapper functions were copied from OpenSSL 1.1.1v's 94 * crypto/ppccap.c. 95 */ 96 97 void sha256_block_p8(void *ctx, const void *inp, size_t len); 98 void sha256_block_ppc(void *ctx, const void *inp, size_t len); 99 void sha256_block_data_order(void *ctx, const void *inp, size_t len); 100 void sha256_block_data_order(void *ctx, const void *inp, size_t len) 101 { 102 OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) : 103 sha256_block_ppc(ctx, inp, len); 104 } 105 106 void sha512_block_p8(void *ctx, const void *inp, size_t len); 107 void sha512_block_ppc(void *ctx, const void *inp, size_t len); 108 void sha512_block_data_order(void *ctx, const void *inp, size_t len); 109 void sha512_block_data_order(void *ctx, const void *inp, size_t len) 110 { 111 OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha512_block_p8(ctx, inp, len) : 112 sha512_block_ppc(ctx, inp, len); 113 } 114 115 void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp, 116 size_t len, const unsigned int key[8], 117 const unsigned int counter[4]); 118 void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp, 119 size_t len, const unsigned int key[8], 120 const unsigned int counter[4]); 121 void ChaCha20_ctr32_vsx(unsigned char *out, const unsigned char *inp, 122 size_t len, const unsigned int key[8], 123 const unsigned int counter[4]); 124 void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, 125 size_t len, const unsigned int key[8], 126 const unsigned int counter[4]); 127 void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, 128 size_t len, const unsigned int key[8], 129 const unsigned int counter[4]) 130 { 131 OPENSSL_ppccap_P & PPC_CRYPTO207 132 ? ChaCha20_ctr32_vsx(out, inp, len, key, counter) 133 : OPENSSL_ppccap_P & PPC_ALTIVEC 134 ? ChaCha20_ctr32_vmx(out, inp, len, key, counter) 135 : ChaCha20_ctr32_int(out, inp, len, key, counter); 136 } 137 138 void poly1305_init_int(void *ctx, const unsigned char key[16]); 139 void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, 140 unsigned int padbit); 141 void poly1305_emit(void *ctx, unsigned char mac[16], 142 const unsigned int nonce[4]); 143 void poly1305_init_fpu(void *ctx, const unsigned char key[16]); 144 void poly1305_blocks_fpu(void *ctx, const unsigned char *inp, size_t len, 145 unsigned int padbit); 146 void poly1305_emit_fpu(void *ctx, unsigned char mac[16], 147 const unsigned int nonce[4]); 148 int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]); 149 int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) 150 { 151 if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) { 152 poly1305_init_fpu(ctx, key); 153 func[0] = (void*)(uintptr_t)poly1305_blocks_fpu; 154 func[1] = (void*)(uintptr_t)poly1305_emit_fpu; 155 } else { 156 poly1305_init_int(ctx, key); 157 func[0] = (void*)(uintptr_t)poly1305_blocks; 158 func[1] = (void*)(uintptr_t)poly1305_emit; 159 } 160 return 1; 161 } 162