tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gcm-ppc.c (3135B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifdef FREEBL_NO_DEPEND
      6 #include "stubs.h"
      7 #endif
      8 #include "gcm.h"
      9 #include "secerr.h"
     10 
     11 #if defined(USE_PPC_CRYPTO)
     12 
     13 SECStatus
     14 gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf)
     15 {
     16    vec_xst_be((vec_u8)ghash->x, 0, outbuf);
     17    return SECSuccess;
     18 }
     19 
     20 static vec_u64
     21 vpmsumd(const vec_u64 a, const vec_u64 b)
     22 {
     23 #if defined(__clang__)
     24    /* Clang uses a different name */
     25    return __builtin_altivec_crypto_vpmsumd(a, b);
     26 #elif (__GNUC__ >= 10) || (__GNUC__ == 9 && __GNUC_MINOR__ >= 3) || \
     27    (__GNUC__ == 8 && __GNUC_MINOR__ >= 4) ||                       \
     28    (__GNUC__ == 7 && __GNUC_MINOR__ >= 5)
     29    /* GCC versions not affected by https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91275 */
     30    return __builtin_crypto_vpmsumd(a, b);
     31 #else
     32    /* GCC versions where this builtin is buggy */
     33    vec_u64 vr;
     34    __asm("vpmsumd %0, %1, %2"
     35          : "=v"(vr)
     36          : "v"(a), "v"(b));
     37    return vr;
     38 #endif
     39 }
     40 
     41 SECStatus
     42 gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf,
     43                unsigned int count)
     44 {
     45    const vec_u8 leftshift = vec_splat_u8(1);
     46    const vec_u64 onebit = (vec_u64){ 1, 0 };
     47    const unsigned long long pd = 0xc2LLU << 56;
     48 
     49    vec_u64 ci, v, r0, r1;
     50    vec_u64 hibit;
     51    unsigned i;
     52 
     53    ci = ghash->x;
     54 
     55    for (i = 0; i < count; i++, buf += 16) {
     56        /* clang needs the following cast away from const; maybe a bug in 7.0.0 */
     57        v = (vec_u64)vec_xl_be(0, (unsigned char *)buf);
     58        ci ^= v;
     59 
     60        /* Do binary mult ghash->X = C * ghash->H (Karatsuba). */
     61        r0 = vpmsumd((vec_u64){ ci[0], 0 }, (vec_u64){ ghash->h[0], 0 });
     62        r1 = vpmsumd((vec_u64){ ci[1], 0 }, (vec_u64){ ghash->h[1], 0 });
     63        v = (vec_u64){ ci[0] ^ ci[1], ghash->h[0] ^ ghash->h[1] };
     64        v = vpmsumd((vec_u64){ v[0], 0 }, (vec_u64){ v[1], 0 });
     65        v ^= r0;
     66        v ^= r1;
     67        r0 ^= (vec_u64){ 0, v[0] };
     68        r1 ^= (vec_u64){ v[1], 0 };
     69 
     70        /* Shift one (multiply by x) as gcm spec is stupid. */
     71        hibit = (vec_u64)vec_splat((vec_u8)r0, 15);
     72        hibit = (vec_u64)vec_rl((vec_u8)hibit, leftshift);
     73        hibit &= onebit;
     74        r0 = vec_sll(r0, leftshift);
     75        r1 = vec_sll(r1, leftshift);
     76        r1 |= hibit;
     77 
     78        /* Reduce */
     79        v = vpmsumd((vec_u64){ r0[0], 0 }, (vec_u64){ pd, 0 });
     80        r0 ^= (vec_u64){ 0, v[0] };
     81        r1 ^= (vec_u64){ v[1], 0 };
     82        v = vpmsumd((vec_u64){ r0[1], 0 }, (vec_u64){ pd, 0 });
     83        r1 ^= v;
     84        ci = r0 ^ r1;
     85    }
     86 
     87    ghash->x = ci;
     88 
     89    return SECSuccess;
     90 }
     91 
     92 SECStatus
     93 gcm_HashInit_hw(gcmHashContext *ghash)
     94 {
     95    ghash->x = (vec_u64)vec_splat_u32(0);
     96    ghash->h = (vec_u64){ ghash->h_low, ghash->h_high };
     97    ghash->ghash_mul = gcm_HashMult_hw;
     98    ghash->hw = PR_TRUE;
     99    return SECSuccess;
    100 }
    101 
    102 SECStatus
    103 gcm_HashZeroX_hw(gcmHashContext *ghash)
    104 {
    105    ghash->x = (vec_u64)vec_splat_u32(0);
    106    return SECSuccess;
    107 }
    108 
    109 #endif /* defined(USE_PPC_CRYPTO) */