1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Accelerated GHASH implementation with Intel PCLMULQDQ-NI 4 * instructions. This file contains accelerated part of ghash 5 * implementation. More information about PCLMULQDQ can be found at: 6 * 7 * http://software.intel.com/en-us/articles/carry-less-multiplication-and-its-usage-for-computing-the-gcm-mode/ 8 * 9 * Copyright (c) 2009 Intel Corp. 10 * Author: Huang Ying <ying.huang@intel.com> 11 * Vinodh Gopal 12 * Erdinc Ozturk 13 * Deniz Karakoyunlu 14 */ 15 16#include <linux/linkage.h> 17#include <asm/inst.h> 18#include <asm/frame.h> 19 20.section .rodata.cst16.bswap_mask, "aM", @progbits, 16 21.align 16 22.Lbswap_mask: 23 .octa 0x000102030405060708090a0b0c0d0e0f 24 25#define DATA %xmm0 26#define SHASH %xmm1 27#define T1 %xmm2 28#define T2 %xmm3 29#define T3 %xmm4 30#define BSWAP %xmm5 31#define IN1 %xmm6 32 33.text 34 35/* 36 * __clmul_gf128mul_ble: internal ABI 37 * input: 38 * DATA: operand1 39 * SHASH: operand2, hash_key << 1 mod poly 40 * output: 41 * DATA: operand1 * operand2 mod poly 42 * changed: 43 * T1 44 * T2 45 * T3 46 */ 47__clmul_gf128mul_ble: 48 movaps DATA, T1 49 pshufd $0b01001110, DATA, T2 50 pshufd $0b01001110, SHASH, T3 51 pxor DATA, T2 52 pxor SHASH, T3 53 54 PCLMULQDQ 0x00 SHASH DATA # DATA = a0 * b0 55 PCLMULQDQ 0x11 SHASH T1 # T1 = a1 * b1 56 PCLMULQDQ 0x00 T3 T2 # T2 = (a1 + a0) * (b1 + b0) 57 pxor DATA, T2 58 pxor T1, T2 # T2 = a0 * b1 + a1 * b0 59 60 movaps T2, T3 61 pslldq $8, T3 62 psrldq $8, T2 63 pxor T3, DATA 64 pxor T2, T1 # <T1:DATA> is result of 65 # carry-less multiplication 66 67 # first phase of the reduction 68 movaps DATA, T3 69 psllq $1, T3 70 pxor DATA, T3 71 psllq $5, T3 72 pxor DATA, T3 73 psllq $57, T3 74 movaps T3, T2 75 pslldq $8, T2 76 psrldq $8, T3 77 pxor T2, DATA 78 pxor T3, T1 79 80 # second phase of the reduction 81 movaps DATA, T2 82 psrlq $5, T2 83 pxor DATA, T2 84 psrlq $1, T2 85 pxor DATA, T2 86 psrlq $1, T2 87 pxor T2, T1 88 pxor T1, DATA 89 ret 90ENDPROC(__clmul_gf128mul_ble) 91 92/* void clmul_ghash_mul(char *dst, const u128 *shash) */ 93ENTRY(clmul_ghash_mul) 94 FRAME_BEGIN 95 movups (%rdi), DATA 96 movups (%rsi), SHASH 97 movaps .Lbswap_mask, BSWAP 98 PSHUFB_XMM BSWAP DATA 99 call __clmul_gf128mul_ble 100 PSHUFB_XMM BSWAP DATA 101 movups DATA, (%rdi) 102 FRAME_END 103 ret 104ENDPROC(clmul_ghash_mul) 105 106/* 107 * void clmul_ghash_update(char *dst, const char *src, unsigned int srclen, 108 * const u128 *shash); 109 */ 110ENTRY(clmul_ghash_update) 111 FRAME_BEGIN 112 cmp $16, %rdx 113 jb .Lupdate_just_ret # check length 114 movaps .Lbswap_mask, BSWAP 115 movups (%rdi), DATA 116 movups (%rcx), SHASH 117 PSHUFB_XMM BSWAP DATA 118.align 4 119.Lupdate_loop: 120 movups (%rsi), IN1 121 PSHUFB_XMM BSWAP IN1 122 pxor IN1, DATA 123 call __clmul_gf128mul_ble 124 sub $16, %rdx 125 add $16, %rsi 126 cmp $16, %rdx 127 jge .Lupdate_loop 128 PSHUFB_XMM BSWAP DATA 129 movups DATA, (%rdi) 130.Lupdate_just_ret: 131 FRAME_END 132 ret 133ENDPROC(clmul_ghash_update) 134