X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fppccap.c;h=2f7cd8e6e7634429e0fc28a8935244f257ce5683;hp=76cfdbde8b7ab3f192008dd4af5fb720aeca8c14;hb=4af14b7b018750bf3584587068211948924738fb;hpb=b3214008e42eba8e8d05b52f22b50570927962c7 diff --git a/crypto/ppccap.c b/crypto/ppccap.c index 76cfdbde8b..2f7cd8e6e7 100644 --- a/crypto/ppccap.c +++ b/crypto/ppccap.c @@ -1,3 +1,12 @@ +/* + * Copyright 2009-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + #include #include #include @@ -13,6 +22,10 @@ # define __power_set(a) (_system_configuration.implementation & (a)) # endif #endif +#if defined(__APPLE__) && defined(__MACH__) +# include +# include +#endif #include #include @@ -26,38 +39,24 @@ static sigset_t all_masked; int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num) { - int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *bp, const BN_ULONG *np, - const BN_ULONG *n0, int num); int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); + int bn_mul4x_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); - if (sizeof(size_t) == 4) { -# if 1 || (defined(__APPLE__) && defined(__MACH__)) - if (num >= 8 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64)) - return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); -# else - /* - * boundary of 32 was experimentally determined on Linux 2.6.22, - * might have to be adjusted on AIX... - */ - if (num >= 32 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64)) { - sigset_t oset; - int ret; - - sigprocmask(SIG_SETMASK, &all_masked, &oset); - ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); - sigprocmask(SIG_SETMASK, &oset, NULL); - - return ret; - } -# endif - } else if ((OPENSSL_ppccap_P & PPC_FPU64)) - /* - * this is a "must" on POWER6, but run-time detection is not - * implemented yet... - */ - return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); + if (num < 4) + return 0; + + if ((num & 3) == 0) + return bn_mul4x_mont_int(rp, ap, bp, np, n0, num); + + /* + * There used to be [optional] call to bn_mul_mont_fpu64 here, + * but above subroutine is faster on contemporary processors. + * Formulation means that there might be old processors where + * FPU code path would be faster, POWER6 perhaps, but there was + * no opportunity to figure it out... + */ return bn_mul_mont_int(rp, ap, bp, np, n0, num); } @@ -79,6 +78,7 @@ void sha512_block_data_order(void *ctx, const void *inp, size_t len) sha512_block_ppc(ctx, inp, len); } +#ifndef OPENSSL_NO_CHACHA void ChaCha20_ctr32_int(unsigned char *out, const unsigned char *inp, size_t len, const unsigned int key[8], const unsigned int counter[4]); @@ -93,7 +93,9 @@ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, ? ChaCha20_ctr32_vmx(out, inp, len, key, counter) : ChaCha20_ctr32_int(out, inp, len, key, counter); } +#endif +#ifndef OPENSSL_NO_POLY1305 void poly1305_init_int(void *ctx, const unsigned char key[16]); void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, unsigned int padbit); @@ -107,16 +109,41 @@ void poly1305_emit_fpu(void *ctx, unsigned char mac[16], int poly1305_init(void *ctx, const unsigned char key[16], void *func[2]) { if (sizeof(size_t) == 4 && (OPENSSL_ppccap_P & PPC_FPU)) { - poly1305_init_fpu(ctx,key); + poly1305_init_fpu(ctx, key); func[0] = poly1305_blocks_fpu; func[1] = poly1305_emit_fpu; } else { - poly1305_init_int(ctx,key); + poly1305_init_int(ctx, key); func[0] = poly1305_blocks; func[1] = poly1305_emit; } return 1; } +#endif + +#ifdef ECP_NISTZ256_ASM +void ecp_nistz256_mul_mont(unsigned long res[4], const unsigned long a[4], + const unsigned long b[4]); + +void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]); +void ecp_nistz256_to_mont(unsigned long res[4], const unsigned long in[4]) +{ + static const unsigned long RR[] = { 0x0000000000000003U, + 0xfffffffbffffffffU, + 0xfffffffffffffffeU, + 0x00000004fffffffdU }; + + ecp_nistz256_mul_mont(res, in, RR); +} + +void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]); +void ecp_nistz256_from_mont(unsigned long res[4], const unsigned long in[4]) +{ + static const unsigned long one[] = { 1, 0, 0, 0 }; + + ecp_nistz256_mul_mont(res, in, one); +} +#endif static sigjmp_buf ill_jmp; static void ill_handler(int sig) @@ -128,6 +155,7 @@ void OPENSSL_fpu_probe(void); void OPENSSL_ppc64_probe(void); void OPENSSL_altivec_probe(void); void OPENSSL_crypto207_probe(void); +void OPENSSL_madd300_probe(void); /* * Use a weak reference to getauxval() so we can use it if it is available @@ -151,6 +179,7 @@ static unsigned long (*getauxval) (unsigned long) = NULL; #define HWCAP2 26 /* AT_HWCAP2 */ #define HWCAP_VEC_CRYPTO (1U << 25) +#define HWCAP_ARCH_3_00 (1U << 23) # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) @@ -208,15 +237,40 @@ void OPENSSL_cpuid_setup(void) if (__power_set(0xffffffffU<<16)) /* POWER8 and later */ OPENSSL_ppccap_P |= PPC_CRYPTO207; + if (__power_set(0xffffffffU<<17)) /* POWER9 and later */ + OPENSSL_ppccap_P |= PPC_MADD300; + return; # endif #endif +#if defined(__APPLE__) && defined(__MACH__) + OPENSSL_ppccap_P |= PPC_FPU; + + { + int val; + size_t len = sizeof(val); + + if (sysctlbyname("hw.optional.64bitops", &val, &len, NULL, 0) == 0) { + if (val) + OPENSSL_ppccap_P |= PPC_FPU64; + } + + len = sizeof(val); + if (sysctlbyname("hw.optional.altivec", &val, &len, NULL, 0) == 0) { + if (val) + OPENSSL_ppccap_P |= PPC_ALTIVEC; + } + + return; + } +#endif + if (getauxval != NULL) { unsigned long hwcap = getauxval(HWCAP); if (hwcap & HWCAP_FPU) { - OPENSSL_ppccap_P |= PPC_FPU; + OPENSSL_ppccap_P |= PPC_FPU; if (sizeof(size_t) == 4) { /* In 32-bit case PPC_FPU64 is always fastest [if option] */ @@ -236,6 +290,10 @@ void OPENSSL_cpuid_setup(void) OPENSSL_ppccap_P |= PPC_CRYPTO207; } + if (hwcap & HWCAP_ARCH_3_00) { + OPENSSL_ppccap_P |= PPC_MADD300; + } + return; } @@ -285,6 +343,11 @@ void OPENSSL_cpuid_setup(void) } } + if (sigsetjmp(ill_jmp, 1) == 0) { + OPENSSL_madd300_probe(); + OPENSSL_ppccap_P |= PPC_MADD300; + } + sigaction(SIGILL, &ill_oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); }