1 | /*
|
---|
2 | * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
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
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <stdio.h>
|
---|
11 | #include "internal/cryptlib.h"
|
---|
12 | #include <openssl/ec.h>
|
---|
13 | #include <openssl/rand.h>
|
---|
14 | #include "crypto/ecx.h"
|
---|
15 | #include "ec_local.h"
|
---|
16 | #include "curve448/curve448_local.h"
|
---|
17 | #include "ecx_backend.h"
|
---|
18 | #include "s390x_arch.h"
|
---|
19 | #include "internal/constant_time.h"
|
---|
20 |
|
---|
21 | static void s390x_x25519_mod_p(unsigned char u[32])
|
---|
22 | {
|
---|
23 | unsigned char u_red[32];
|
---|
24 | unsigned int c = 0;
|
---|
25 | int i;
|
---|
26 |
|
---|
27 | memcpy(u_red, u, sizeof(u_red));
|
---|
28 |
|
---|
29 | c += (unsigned int)u_red[31] + 19;
|
---|
30 | u_red[31] = (unsigned char)c;
|
---|
31 | c >>= 8;
|
---|
32 |
|
---|
33 | for (i = 30; i >= 0; i--) {
|
---|
34 | c += (unsigned int)u_red[i];
|
---|
35 | u_red[i] = (unsigned char)c;
|
---|
36 | c >>= 8;
|
---|
37 | }
|
---|
38 |
|
---|
39 | c = (u_red[0] & 0x80) >> 7;
|
---|
40 | u_red[0] &= 0x7f;
|
---|
41 | constant_time_cond_swap_buff(0 - (unsigned char)c,
|
---|
42 | u, u_red, sizeof(u_red));
|
---|
43 | }
|
---|
44 |
|
---|
45 | static void s390x_x448_mod_p(unsigned char u[56])
|
---|
46 | {
|
---|
47 | unsigned char u_red[56];
|
---|
48 | unsigned int c = 0;
|
---|
49 | int i;
|
---|
50 |
|
---|
51 | memcpy(u_red, u, sizeof(u_red));
|
---|
52 |
|
---|
53 | c += (unsigned int)u_red[55] + 1;
|
---|
54 | u_red[55] = (unsigned char)c;
|
---|
55 | c >>= 8;
|
---|
56 |
|
---|
57 | for (i = 54; i >= 28; i--) {
|
---|
58 | c += (unsigned int)u_red[i];
|
---|
59 | u_red[i] = (unsigned char)c;
|
---|
60 | c >>= 8;
|
---|
61 | }
|
---|
62 |
|
---|
63 | c += (unsigned int)u_red[27] + 1;
|
---|
64 | u_red[27] = (unsigned char)c;
|
---|
65 | c >>= 8;
|
---|
66 |
|
---|
67 | for (i = 26; i >= 0; i--) {
|
---|
68 | c += (unsigned int)u_red[i];
|
---|
69 | u_red[i] = (unsigned char)c;
|
---|
70 | c >>= 8;
|
---|
71 | }
|
---|
72 |
|
---|
73 | constant_time_cond_swap_buff(0 - (unsigned char)c,
|
---|
74 | u, u_red, sizeof(u_red));
|
---|
75 | }
|
---|
76 |
|
---|
77 | int s390x_x25519_mul(unsigned char u_dst[32],
|
---|
78 | const unsigned char u_src[32],
|
---|
79 | const unsigned char d_src[32])
|
---|
80 | {
|
---|
81 | union {
|
---|
82 | struct {
|
---|
83 | unsigned char u_dst[32];
|
---|
84 | unsigned char u_src[32];
|
---|
85 | unsigned char d_src[32];
|
---|
86 | } x25519;
|
---|
87 | unsigned long long buff[512];
|
---|
88 | } param;
|
---|
89 | int rc;
|
---|
90 |
|
---|
91 | memset(¶m, 0, sizeof(param));
|
---|
92 |
|
---|
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);
|
---|
96 |
|
---|
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;
|
---|
101 |
|
---|
102 | rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
|
---|
103 | if (rc == 1)
|
---|
104 | s390x_flip_endian32(u_dst, param.x25519.u_dst);
|
---|
105 |
|
---|
106 | OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
|
---|
107 | return rc;
|
---|
108 | }
|
---|
109 |
|
---|
110 | int s390x_x448_mul(unsigned char u_dst[56],
|
---|
111 | const unsigned char u_src[56],
|
---|
112 | const unsigned char d_src[56])
|
---|
113 | {
|
---|
114 | union {
|
---|
115 | struct {
|
---|
116 | unsigned char u_dst[64];
|
---|
117 | unsigned char u_src[64];
|
---|
118 | unsigned char d_src[64];
|
---|
119 | } x448;
|
---|
120 | unsigned long long buff[512];
|
---|
121 | } param;
|
---|
122 | int rc;
|
---|
123 |
|
---|
124 | memset(¶m, 0, sizeof(param));
|
---|
125 |
|
---|
126 | memcpy(param.x448.u_src, u_src, 56);
|
---|
127 | memcpy(param.x448.d_src, d_src, 56);
|
---|
128 |
|
---|
129 | s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
|
---|
130 | s390x_x448_mod_p(param.x448.u_src + 8);
|
---|
131 |
|
---|
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;
|
---|
135 |
|
---|
136 | rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
|
---|
137 | if (rc == 1) {
|
---|
138 | s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
|
---|
139 | memcpy(u_dst, param.x448.u_dst, 56);
|
---|
140 | }
|
---|
141 |
|
---|
142 | OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
|
---|
143 | return rc;
|
---|
144 | }
|
---|
145 |
|
---|
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])
|
---|
151 | {
|
---|
152 | union {
|
---|
153 | struct {
|
---|
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];
|
---|
159 | } ed25519;
|
---|
160 | unsigned long long buff[512];
|
---|
161 | } param;
|
---|
162 | int rc;
|
---|
163 |
|
---|
164 | memset(¶m, 0, sizeof(param));
|
---|
165 |
|
---|
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);
|
---|
169 |
|
---|
170 | rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
|
---|
171 | if (rc == 1) {
|
---|
172 | s390x_flip_endian32(x_dst, param.ed25519.x_dst);
|
---|
173 | s390x_flip_endian32(y_dst, param.ed25519.y_dst);
|
---|
174 | }
|
---|
175 |
|
---|
176 | OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
|
---|
177 | return rc;
|
---|
178 | }
|
---|
179 |
|
---|
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])
|
---|
185 | {
|
---|
186 | union {
|
---|
187 | struct {
|
---|
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];
|
---|
193 | } ed448;
|
---|
194 | unsigned long long buff[512];
|
---|
195 | } param;
|
---|
196 | int rc;
|
---|
197 |
|
---|
198 | memset(¶m, 0, sizeof(param));
|
---|
199 |
|
---|
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);
|
---|
206 |
|
---|
207 | rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
|
---|
208 | if (rc == 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);
|
---|
213 | }
|
---|
214 |
|
---|
215 | OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
|
---|
216 | return rc;
|
---|
217 | }
|
---|