2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/ec.h>
13 #include <openssl/rand.h>
14 #include "crypto/ecx.h"
16 #include "curve448/curve448_local.h"
17 #include "ecx_backend.h"
18 #include "s390x_arch.h"
19 #include "internal/constant_time.h"
21 static void s390x_x25519_mod_p(unsigned char u[32])
23 unsigned char u_red[32];
27 memcpy(u_red, u, sizeof(u_red));
29 c += (unsigned int)u_red[31] + 19;
30 u_red[31] = (unsigned char)c;
33 for (i = 30; i >= 0; i--) {
34 c += (unsigned int)u_red[i];
35 u_red[i] = (unsigned char)c;
39 c = (u_red[0] & 0x80) >> 7;
41 constant_time_cond_swap_buff(0 - (unsigned char)c,
42 u, u_red, sizeof(u_red));
45 static void s390x_x448_mod_p(unsigned char u[56])
47 unsigned char u_red[56];
51 memcpy(u_red, u, sizeof(u_red));
53 c += (unsigned int)u_red[55] + 1;
54 u_red[55] = (unsigned char)c;
57 for (i = 54; i >= 28; i--) {
58 c += (unsigned int)u_red[i];
59 u_red[i] = (unsigned char)c;
63 c += (unsigned int)u_red[27] + 1;
64 u_red[27] = (unsigned char)c;
67 for (i = 26; i >= 0; i--) {
68 c += (unsigned int)u_red[i];
69 u_red[i] = (unsigned char)c;
73 constant_time_cond_swap_buff(0 - (unsigned char)c,
74 u, u_red, sizeof(u_red));
77 int s390x_x25519_mul(unsigned char u_dst[32],
78 const unsigned char u_src[32],
79 const unsigned char d_src[32])
83 unsigned char u_dst[32];
84 unsigned char u_src[32];
85 unsigned char d_src[32];
87 unsigned long long buff[512];
91 memset(¶m, 0, sizeof(param));
93 s390x_flip_endian32(param.x25519.u_src, u_src);
94 param.x25519.u_src[0] &= 0x7f;
95 s390x_x25519_mod_p(param.x25519.u_src);
97 s390x_flip_endian32(param.x25519.d_src, d_src);
98 param.x25519.d_src[31] &= 248;
99 param.x25519.d_src[0] &= 127;
100 param.x25519.d_src[0] |= 64;
102 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
104 s390x_flip_endian32(u_dst, param.x25519.u_dst);
106 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
110 int s390x_x448_mul(unsigned char u_dst[56],
111 const unsigned char u_src[56],
112 const unsigned char d_src[56])
116 unsigned char u_dst[64];
117 unsigned char u_src[64];
118 unsigned char d_src[64];
120 unsigned long long buff[512];
124 memset(¶m, 0, sizeof(param));
126 memcpy(param.x448.u_src, u_src, 56);
127 memcpy(param.x448.d_src, d_src, 56);
129 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
130 s390x_x448_mod_p(param.x448.u_src + 8);
132 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
133 param.x448.d_src[63] &= 252;
134 param.x448.d_src[8] |= 128;
136 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
138 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
139 memcpy(u_dst, param.x448.u_dst, 56);
142 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
146 int s390x_ed25519_mul(unsigned char x_dst[32],
147 unsigned char y_dst[32],
148 const unsigned char x_src[32],
149 const unsigned char y_src[32],
150 const unsigned char d_src[32])
154 unsigned char x_dst[32];
155 unsigned char y_dst[32];
156 unsigned char x_src[32];
157 unsigned char y_src[32];
158 unsigned char d_src[32];
160 unsigned long long buff[512];
164 memset(¶m, 0, sizeof(param));
166 s390x_flip_endian32(param.ed25519.x_src, x_src);
167 s390x_flip_endian32(param.ed25519.y_src, y_src);
168 s390x_flip_endian32(param.ed25519.d_src, d_src);
170 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
172 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
173 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
176 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
180 int s390x_ed448_mul(unsigned char x_dst[57],
181 unsigned char y_dst[57],
182 const unsigned char x_src[57],
183 const unsigned char y_src[57],
184 const unsigned char d_src[57])
188 unsigned char x_dst[64];
189 unsigned char y_dst[64];
190 unsigned char x_src[64];
191 unsigned char y_src[64];
192 unsigned char d_src[64];
194 unsigned long long buff[512];
198 memset(¶m, 0, sizeof(param));
200 memcpy(param.ed448.x_src, x_src, 57);
201 memcpy(param.ed448.y_src, y_src, 57);
202 memcpy(param.ed448.d_src, d_src, 57);
203 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
204 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
205 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
207 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
209 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
210 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
211 memcpy(x_dst, param.ed448.x_dst, 57);
212 memcpy(y_dst, param.ed448.y_dst, 57);
215 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));