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 ossl_cipher_setkey_t vpaes_set_encrypt_key; 42 ossl_cipher_setkey_t vpaes_set_decrypt_key; 43 44 void 45 ossl_cpuid(struct ossl_softc *sc) 46 { 47 if (cpu_features2 & PPC_FEATURE2_HAS_VEC_CRYPTO) { 48 OPENSSL_ppccap_P |= PPC_CRYPTO207; 49 } 50 51 if (cpu_features2 & PPC_FEATURE2_ARCH_3_00) { 52 OPENSSL_ppccap_P |= PPC_MADD300; 53 } 54 55 if (cpu_features & PPC_FEATURE_64) { 56 OPENSSL_ppccap_P |= PPC_MFTB; 57 } else { 58 OPENSSL_ppccap_P |= PPC_MFSPR268; 59 } 60 61 if (cpu_features & PPC_FEATURE_HAS_FPU) { 62 OPENSSL_ppccap_P |= PPC_FPU; 63 64 if (cpu_features & PPC_FEATURE_64) { 65 OPENSSL_ppccap_P |= PPC_FPU64; 66 } 67 } 68 69 if (cpu_features & PPC_FEATURE_HAS_ALTIVEC) { 70 OPENSSL_ppccap_P |= PPC_ALTIVEC; 71 } 72 73 /* Pick P8 crypto if available, otherwise fall back to altivec */ 74 if (OPENSSL_ppccap_P & PPC_CRYPTO207) { 75 ossl_cipher_aes_cbc.set_encrypt_key = aes_p8_set_encrypt_key; 76 ossl_cipher_aes_cbc.set_decrypt_key = aes_p8_set_decrypt_key; 77 sc->has_aes = true; 78 } else if (OPENSSL_ppccap_P & PPC_ALTIVEC) { 79 ossl_cipher_aes_cbc.set_encrypt_key = vpaes_set_encrypt_key; 80 ossl_cipher_aes_cbc.set_decrypt_key = vpaes_set_decrypt_key; 81 sc->has_aes = true; 82 } 83 } 84 85 /* 86 * The following trivial wrapper functions were copied from OpenSSL 1.1.1v's 87 * crypto/ppccap.c. 88 */ 89 90 void sha256_block_p8(void *ctx, const void *inp, size_t len); 91 void sha256_block_ppc(void *ctx, const void *inp, size_t len); 92 void sha256_block_data_order(void *ctx, const void *inp, size_t len); 93 void sha256_block_data_order(void *ctx, const void *inp, size_t len) 94 { 95 OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) : 96 sha256_block_ppc(ctx, inp, len); 97 } 98 99 void sha512_block_p8(void *ctx, const void *inp, size_t len); 100 void sha512_block_ppc(void *ctx, const void *inp, size_t len); 101 void sha512_block_data_order(void *ctx, const void *inp, size_t len); 102 void sha512_block_data_order(void *ctx, const void *inp, size_t len) 103 { 104 OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha512_block_p8(ctx, inp, len) : 105 sha512_block_ppc(ctx, inp, len); 106 } 107 108 void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp, 109 size_t len, const unsigned int key[8], 110 const unsigned int counter[4]); 111 void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp, 112 size_t len, const unsigned int key[8], 113 const unsigned int counter[4]); 114 void ChaCha20_ctr32_vsx(unsigned char *out, const unsigned char *inp, 115 size_t len, const unsigned int key[8], 116 const unsigned int counter[4]); 117 void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, 118 size_t len, const unsigned int key[8], 119 const unsigned int counter[4]); 120 void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, 121 size_t len, const unsigned int key[8], 122 const unsigned int counter[4]) 123 { 124 OPENSSL_ppccap_P & PPC_CRYPTO207 125 ? ChaCha20_ctr32_vsx(out, inp, len, key, counter) 126 : OPENSSL_ppccap_P & PPC_ALTIVEC 127 ? ChaCha20_ctr32_vmx(out, inp, len, key, counter) 128 : ChaCha20_ctr32_int(out, inp, len, key, counter); 129 } 130 131 void poly1305_init_int(void *ctx, const unsigned char key[16]); 132 void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, 133 unsigned int padbit); 134 void poly1305_emit(void *ctx, unsigned char mac[16], 135 const unsigned int nonce[4]); 136 void poly1305_init_fpu(void *ctx, const unsigned char key[16]); 137 void poly1305_blocks_fpu(void *ctx, const unsigned char *inp, size_t len, 138 unsigned int padbit); 139 void poly1305_emit_fpu(void *ctx, unsigned char mac[16], 140 const unsigned int nonce[4]); 141 int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]); 142 int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) 143 { 144 if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) { 145 poly1305_init_fpu(ctx, key); 146 func[0] = (void*)(uintptr_t)poly1305_blocks_fpu; 147 func[1] = (void*)(uintptr_t)poly1305_emit_fpu; 148 } else { 149 poly1305_init_int(ctx, key); 150 func[0] = (void*)(uintptr_t)poly1305_blocks; 151 func[1] = (void*)(uintptr_t)poly1305_emit; 152 } 153 return 1; 154 } 155