162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Fast MD5 implementation for PPC 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <asm/ppc_asm.h> 862306a36Sopenharmony_ci#include <asm/asm-offsets.h> 962306a36Sopenharmony_ci#include <asm/asm-compat.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define rHP r3 1262306a36Sopenharmony_ci#define rWP r4 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define rH0 r0 1562306a36Sopenharmony_ci#define rH1 r6 1662306a36Sopenharmony_ci#define rH2 r7 1762306a36Sopenharmony_ci#define rH3 r5 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define rW00 r8 2062306a36Sopenharmony_ci#define rW01 r9 2162306a36Sopenharmony_ci#define rW02 r10 2262306a36Sopenharmony_ci#define rW03 r11 2362306a36Sopenharmony_ci#define rW04 r12 2462306a36Sopenharmony_ci#define rW05 r14 2562306a36Sopenharmony_ci#define rW06 r15 2662306a36Sopenharmony_ci#define rW07 r16 2762306a36Sopenharmony_ci#define rW08 r17 2862306a36Sopenharmony_ci#define rW09 r18 2962306a36Sopenharmony_ci#define rW10 r19 3062306a36Sopenharmony_ci#define rW11 r20 3162306a36Sopenharmony_ci#define rW12 r21 3262306a36Sopenharmony_ci#define rW13 r22 3362306a36Sopenharmony_ci#define rW14 r23 3462306a36Sopenharmony_ci#define rW15 r24 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#define rT0 r25 3762306a36Sopenharmony_ci#define rT1 r26 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define INITIALIZE \ 4062306a36Sopenharmony_ci PPC_STLU r1,-INT_FRAME_SIZE(r1); \ 4162306a36Sopenharmony_ci SAVE_GPRS(14, 26, r1) /* push registers onto stack */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define FINALIZE \ 4462306a36Sopenharmony_ci REST_GPRS(14, 26, r1); /* pop registers from stack */ \ 4562306a36Sopenharmony_ci addi r1,r1,INT_FRAME_SIZE 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN__ 4862306a36Sopenharmony_ci#define LOAD_DATA(reg, off) \ 4962306a36Sopenharmony_ci lwbrx reg,0,rWP; /* load data */ 5062306a36Sopenharmony_ci#define INC_PTR \ 5162306a36Sopenharmony_ci addi rWP,rWP,4; /* increment per word */ 5262306a36Sopenharmony_ci#define NEXT_BLOCK /* nothing to do */ 5362306a36Sopenharmony_ci#else 5462306a36Sopenharmony_ci#define LOAD_DATA(reg, off) \ 5562306a36Sopenharmony_ci lwz reg,off(rWP); /* load data */ 5662306a36Sopenharmony_ci#define INC_PTR /* nothing to do */ 5762306a36Sopenharmony_ci#define NEXT_BLOCK \ 5862306a36Sopenharmony_ci addi rWP,rWP,64; /* increment per block */ 5962306a36Sopenharmony_ci#endif 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define R_00_15(a, b, c, d, w0, w1, p, q, off, k0h, k0l, k1h, k1l) \ 6262306a36Sopenharmony_ci LOAD_DATA(w0, off) /* W */ \ 6362306a36Sopenharmony_ci and rT0,b,c; /* 1: f = b and c */ \ 6462306a36Sopenharmony_ci INC_PTR /* ptr++ */ \ 6562306a36Sopenharmony_ci andc rT1,d,b; /* 1: f' = ~b and d */ \ 6662306a36Sopenharmony_ci LOAD_DATA(w1, off+4) /* W */ \ 6762306a36Sopenharmony_ci or rT0,rT0,rT1; /* 1: f = f or f' */ \ 6862306a36Sopenharmony_ci addi w0,w0,k0l; /* 1: wk = w + k */ \ 6962306a36Sopenharmony_ci add a,a,rT0; /* 1: a = a + f */ \ 7062306a36Sopenharmony_ci addis w0,w0,k0h; /* 1: wk = w + k' */ \ 7162306a36Sopenharmony_ci addis w1,w1,k1h; /* 2: wk = w + k */ \ 7262306a36Sopenharmony_ci add a,a,w0; /* 1: a = a + wk */ \ 7362306a36Sopenharmony_ci addi w1,w1,k1l; /* 2: wk = w + k' */ \ 7462306a36Sopenharmony_ci rotrwi a,a,p; /* 1: a = a rotl x */ \ 7562306a36Sopenharmony_ci add d,d,w1; /* 2: a = a + wk */ \ 7662306a36Sopenharmony_ci add a,a,b; /* 1: a = a + b */ \ 7762306a36Sopenharmony_ci and rT0,a,b; /* 2: f = b and c */ \ 7862306a36Sopenharmony_ci andc rT1,c,a; /* 2: f' = ~b and d */ \ 7962306a36Sopenharmony_ci or rT0,rT0,rT1; /* 2: f = f or f' */ \ 8062306a36Sopenharmony_ci add d,d,rT0; /* 2: a = a + f */ \ 8162306a36Sopenharmony_ci INC_PTR /* ptr++ */ \ 8262306a36Sopenharmony_ci rotrwi d,d,q; /* 2: a = a rotl x */ \ 8362306a36Sopenharmony_ci add d,d,a; /* 2: a = a + b */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define R_16_31(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 8662306a36Sopenharmony_ci andc rT0,c,d; /* 1: f = c and ~d */ \ 8762306a36Sopenharmony_ci and rT1,b,d; /* 1: f' = b and d */ \ 8862306a36Sopenharmony_ci addi w0,w0,k0l; /* 1: wk = w + k */ \ 8962306a36Sopenharmony_ci or rT0,rT0,rT1; /* 1: f = f or f' */ \ 9062306a36Sopenharmony_ci addis w0,w0,k0h; /* 1: wk = w + k' */ \ 9162306a36Sopenharmony_ci add a,a,rT0; /* 1: a = a + f */ \ 9262306a36Sopenharmony_ci addi w1,w1,k1l; /* 2: wk = w + k */ \ 9362306a36Sopenharmony_ci add a,a,w0; /* 1: a = a + wk */ \ 9462306a36Sopenharmony_ci addis w1,w1,k1h; /* 2: wk = w + k' */ \ 9562306a36Sopenharmony_ci andc rT0,b,c; /* 2: f = c and ~d */ \ 9662306a36Sopenharmony_ci rotrwi a,a,p; /* 1: a = a rotl x */ \ 9762306a36Sopenharmony_ci add a,a,b; /* 1: a = a + b */ \ 9862306a36Sopenharmony_ci add d,d,w1; /* 2: a = a + wk */ \ 9962306a36Sopenharmony_ci and rT1,a,c; /* 2: f' = b and d */ \ 10062306a36Sopenharmony_ci or rT0,rT0,rT1; /* 2: f = f or f' */ \ 10162306a36Sopenharmony_ci add d,d,rT0; /* 2: a = a + f */ \ 10262306a36Sopenharmony_ci rotrwi d,d,q; /* 2: a = a rotl x */ \ 10362306a36Sopenharmony_ci add d,d,a; /* 2: a = a +b */ 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci#define R_32_47(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 10662306a36Sopenharmony_ci xor rT0,b,c; /* 1: f' = b xor c */ \ 10762306a36Sopenharmony_ci addi w0,w0,k0l; /* 1: wk = w + k */ \ 10862306a36Sopenharmony_ci xor rT1,rT0,d; /* 1: f = f xor f' */ \ 10962306a36Sopenharmony_ci addis w0,w0,k0h; /* 1: wk = w + k' */ \ 11062306a36Sopenharmony_ci add a,a,rT1; /* 1: a = a + f */ \ 11162306a36Sopenharmony_ci addi w1,w1,k1l; /* 2: wk = w + k */ \ 11262306a36Sopenharmony_ci add a,a,w0; /* 1: a = a + wk */ \ 11362306a36Sopenharmony_ci addis w1,w1,k1h; /* 2: wk = w + k' */ \ 11462306a36Sopenharmony_ci rotrwi a,a,p; /* 1: a = a rotl x */ \ 11562306a36Sopenharmony_ci add d,d,w1; /* 2: a = a + wk */ \ 11662306a36Sopenharmony_ci add a,a,b; /* 1: a = a + b */ \ 11762306a36Sopenharmony_ci xor rT1,rT0,a; /* 2: f = b xor f' */ \ 11862306a36Sopenharmony_ci add d,d,rT1; /* 2: a = a + f */ \ 11962306a36Sopenharmony_ci rotrwi d,d,q; /* 2: a = a rotl x */ \ 12062306a36Sopenharmony_ci add d,d,a; /* 2: a = a + b */ 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci#define R_48_63(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ 12362306a36Sopenharmony_ci addi w0,w0,k0l; /* 1: w = w + k */ \ 12462306a36Sopenharmony_ci orc rT0,b,d; /* 1: f = b or ~d */ \ 12562306a36Sopenharmony_ci addis w0,w0,k0h; /* 1: w = w + k' */ \ 12662306a36Sopenharmony_ci xor rT0,rT0,c; /* 1: f = f xor c */ \ 12762306a36Sopenharmony_ci add a,a,w0; /* 1: a = a + wk */ \ 12862306a36Sopenharmony_ci addi w1,w1,k1l; /* 2: w = w + k */ \ 12962306a36Sopenharmony_ci add a,a,rT0; /* 1: a = a + f */ \ 13062306a36Sopenharmony_ci addis w1,w1,k1h; /* 2: w = w + k' */ \ 13162306a36Sopenharmony_ci rotrwi a,a,p; /* 1: a = a rotl x */ \ 13262306a36Sopenharmony_ci add a,a,b; /* 1: a = a + b */ \ 13362306a36Sopenharmony_ci orc rT0,a,c; /* 2: f = b or ~d */ \ 13462306a36Sopenharmony_ci add d,d,w1; /* 2: a = a + wk */ \ 13562306a36Sopenharmony_ci xor rT0,rT0,b; /* 2: f = f xor c */ \ 13662306a36Sopenharmony_ci add d,d,rT0; /* 2: a = a + f */ \ 13762306a36Sopenharmony_ci rotrwi d,d,q; /* 2: a = a rotl x */ \ 13862306a36Sopenharmony_ci add d,d,a; /* 2: a = a + b */ 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci_GLOBAL(ppc_md5_transform) 14162306a36Sopenharmony_ci INITIALIZE 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci mtctr r5 14462306a36Sopenharmony_ci lwz rH0,0(rHP) 14562306a36Sopenharmony_ci lwz rH1,4(rHP) 14662306a36Sopenharmony_ci lwz rH2,8(rHP) 14762306a36Sopenharmony_ci lwz rH3,12(rHP) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cippc_md5_main: 15062306a36Sopenharmony_ci R_00_15(rH0, rH1, rH2, rH3, rW00, rW01, 25, 20, 0, 15162306a36Sopenharmony_ci 0xd76b, -23432, 0xe8c8, -18602) 15262306a36Sopenharmony_ci R_00_15(rH2, rH3, rH0, rH1, rW02, rW03, 15, 10, 8, 15362306a36Sopenharmony_ci 0x2420, 0x70db, 0xc1be, -12562) 15462306a36Sopenharmony_ci R_00_15(rH0, rH1, rH2, rH3, rW04, rW05, 25, 20, 16, 15562306a36Sopenharmony_ci 0xf57c, 0x0faf, 0x4788, -14806) 15662306a36Sopenharmony_ci R_00_15(rH2, rH3, rH0, rH1, rW06, rW07, 15, 10, 24, 15762306a36Sopenharmony_ci 0xa830, 0x4613, 0xfd47, -27391) 15862306a36Sopenharmony_ci R_00_15(rH0, rH1, rH2, rH3, rW08, rW09, 25, 20, 32, 15962306a36Sopenharmony_ci 0x6981, -26408, 0x8b45, -2129) 16062306a36Sopenharmony_ci R_00_15(rH2, rH3, rH0, rH1, rW10, rW11, 15, 10, 40, 16162306a36Sopenharmony_ci 0xffff, 0x5bb1, 0x895d, -10306) 16262306a36Sopenharmony_ci R_00_15(rH0, rH1, rH2, rH3, rW12, rW13, 25, 20, 48, 16362306a36Sopenharmony_ci 0x6b90, 0x1122, 0xfd98, 0x7193) 16462306a36Sopenharmony_ci R_00_15(rH2, rH3, rH0, rH1, rW14, rW15, 15, 10, 56, 16562306a36Sopenharmony_ci 0xa679, 0x438e, 0x49b4, 0x0821) 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci R_16_31(rH0, rH1, rH2, rH3, rW01, rW06, 27, 23, 16862306a36Sopenharmony_ci 0x0d56, 0x6e0c, 0x1810, 0x6d2d) 16962306a36Sopenharmony_ci R_16_31(rH2, rH3, rH0, rH1, rW11, rW00, 18, 12, 17062306a36Sopenharmony_ci 0x9d02, -32109, 0x124c, 0x2332) 17162306a36Sopenharmony_ci R_16_31(rH0, rH1, rH2, rH3, rW05, rW10, 27, 23, 17262306a36Sopenharmony_ci 0x8ea7, 0x4a33, 0x0245, -18270) 17362306a36Sopenharmony_ci R_16_31(rH2, rH3, rH0, rH1, rW15, rW04, 18, 12, 17462306a36Sopenharmony_ci 0x8eee, -8608, 0xf258, -5095) 17562306a36Sopenharmony_ci R_16_31(rH0, rH1, rH2, rH3, rW09, rW14, 27, 23, 17662306a36Sopenharmony_ci 0x969d, -10697, 0x1cbe, -15288) 17762306a36Sopenharmony_ci R_16_31(rH2, rH3, rH0, rH1, rW03, rW08, 18, 12, 17862306a36Sopenharmony_ci 0x3317, 0x3e99, 0xdbd9, 0x7c15) 17962306a36Sopenharmony_ci R_16_31(rH0, rH1, rH2, rH3, rW13, rW02, 27, 23, 18062306a36Sopenharmony_ci 0xac4b, 0x7772, 0xd8cf, 0x331d) 18162306a36Sopenharmony_ci R_16_31(rH2, rH3, rH0, rH1, rW07, rW12, 18, 12, 18262306a36Sopenharmony_ci 0x6a28, 0x6dd8, 0x219a, 0x3b68) 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci R_32_47(rH0, rH1, rH2, rH3, rW05, rW08, 28, 21, 18562306a36Sopenharmony_ci 0x29cb, 0x28e5, 0x4218, -7788) 18662306a36Sopenharmony_ci R_32_47(rH2, rH3, rH0, rH1, rW11, rW14, 16, 9, 18762306a36Sopenharmony_ci 0x473f, 0x06d1, 0x3aae, 0x3036) 18862306a36Sopenharmony_ci R_32_47(rH0, rH1, rH2, rH3, rW01, rW04, 28, 21, 18962306a36Sopenharmony_ci 0xaea1, -15134, 0x640b, -11295) 19062306a36Sopenharmony_ci R_32_47(rH2, rH3, rH0, rH1, rW07, rW10, 16, 9, 19162306a36Sopenharmony_ci 0x8f4c, 0x4887, 0xbc7c, -22499) 19262306a36Sopenharmony_ci R_32_47(rH0, rH1, rH2, rH3, rW13, rW00, 28, 21, 19362306a36Sopenharmony_ci 0x7eb8, -27199, 0x00ea, 0x6050) 19462306a36Sopenharmony_ci R_32_47(rH2, rH3, rH0, rH1, rW03, rW06, 16, 9, 19562306a36Sopenharmony_ci 0xe01a, 0x22fe, 0x4447, 0x69c5) 19662306a36Sopenharmony_ci R_32_47(rH0, rH1, rH2, rH3, rW09, rW12, 28, 21, 19762306a36Sopenharmony_ci 0xb7f3, 0x0253, 0x59b1, 0x4d5b) 19862306a36Sopenharmony_ci R_32_47(rH2, rH3, rH0, rH1, rW15, rW02, 16, 9, 19962306a36Sopenharmony_ci 0x4701, -27017, 0xc7bd, -19859) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci R_48_63(rH0, rH1, rH2, rH3, rW00, rW07, 26, 22, 20262306a36Sopenharmony_ci 0x0988, -1462, 0x4c70, -19401) 20362306a36Sopenharmony_ci R_48_63(rH2, rH3, rH0, rH1, rW14, rW05, 17, 11, 20462306a36Sopenharmony_ci 0xadaf, -5221, 0xfc99, 0x66f7) 20562306a36Sopenharmony_ci R_48_63(rH0, rH1, rH2, rH3, rW12, rW03, 26, 22, 20662306a36Sopenharmony_ci 0x7e80, -16418, 0xba1e, -25587) 20762306a36Sopenharmony_ci R_48_63(rH2, rH3, rH0, rH1, rW10, rW01, 17, 11, 20862306a36Sopenharmony_ci 0x4130, 0x380d, 0xe0c5, 0x738d) 20962306a36Sopenharmony_ci lwz rW00,0(rHP) 21062306a36Sopenharmony_ci R_48_63(rH0, rH1, rH2, rH3, rW08, rW15, 26, 22, 21162306a36Sopenharmony_ci 0xe837, -30770, 0xde8a, 0x69e8) 21262306a36Sopenharmony_ci lwz rW14,4(rHP) 21362306a36Sopenharmony_ci R_48_63(rH2, rH3, rH0, rH1, rW06, rW13, 17, 11, 21462306a36Sopenharmony_ci 0x9e79, 0x260f, 0x256d, -27941) 21562306a36Sopenharmony_ci lwz rW12,8(rHP) 21662306a36Sopenharmony_ci R_48_63(rH0, rH1, rH2, rH3, rW04, rW11, 26, 22, 21762306a36Sopenharmony_ci 0xab75, -20775, 0x4f9e, -28397) 21862306a36Sopenharmony_ci lwz rW10,12(rHP) 21962306a36Sopenharmony_ci R_48_63(rH2, rH3, rH0, rH1, rW02, rW09, 17, 11, 22062306a36Sopenharmony_ci 0x662b, 0x7c56, 0x11b2, 0x0358) 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci add rH0,rH0,rW00 22362306a36Sopenharmony_ci stw rH0,0(rHP) 22462306a36Sopenharmony_ci add rH1,rH1,rW14 22562306a36Sopenharmony_ci stw rH1,4(rHP) 22662306a36Sopenharmony_ci add rH2,rH2,rW12 22762306a36Sopenharmony_ci stw rH2,8(rHP) 22862306a36Sopenharmony_ci add rH3,rH3,rW10 22962306a36Sopenharmony_ci stw rH3,12(rHP) 23062306a36Sopenharmony_ci NEXT_BLOCK 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci bdnz ppc_md5_main 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci FINALIZE 23562306a36Sopenharmony_ci blr 236