s390x assembly pack: add KIMD/KLMD code path for sha3/shake
[openssl.git] / crypto / evp / m_sha3.c
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <string.h>
12
13 #include <openssl/evp.h>
14 #include <openssl/objects.h>
15 #include "internal/evp_int.h"
16 #include "evp_locl.h"
17
18 size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len,
19                    size_t r);
20 void SHA3_squeeze(uint64_t A[5][5], unsigned char *out, size_t len, size_t r);
21
22 #define KECCAK1600_WIDTH 1600
23
24 typedef struct {
25     uint64_t A[5][5];
26     size_t block_size;          /* cached ctx->digest->block_size */
27     size_t md_size;             /* output length, variable in XOF */
28     size_t num;                 /* used bytes in below buffer */
29     unsigned char buf[KECCAK1600_WIDTH / 8 - 32];
30     unsigned char pad;
31 } KECCAK1600_CTX;
32
33 static int init(EVP_MD_CTX *evp_ctx, unsigned char pad)
34 {
35     KECCAK1600_CTX *ctx = evp_ctx->md_data;
36     size_t bsz = evp_ctx->digest->block_size;
37
38     if (bsz <= sizeof(ctx->buf)) {
39         memset(ctx->A, 0, sizeof(ctx->A));
40
41         ctx->num = 0;
42         ctx->block_size = bsz;
43         ctx->md_size = evp_ctx->digest->md_size;
44         ctx->pad = pad;
45
46         return 1;
47     }
48
49     return 0;
50 }
51
52 static int sha3_init(EVP_MD_CTX *evp_ctx)
53 {
54     return init(evp_ctx, '\x06');
55 }
56
57 static int shake_init(EVP_MD_CTX *evp_ctx)
58 {
59     return init(evp_ctx, '\x1f');
60 }
61
62 static int sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
63 {
64     KECCAK1600_CTX *ctx = evp_ctx->md_data;
65     const unsigned char *inp = _inp;
66     size_t bsz = ctx->block_size;
67     size_t num, rem;
68
69     if (len == 0)
70         return 1;
71
72     if ((num = ctx->num) != 0) {      /* process intermediate buffer? */
73         rem = bsz - num;
74
75         if (len < rem) {
76             memcpy(ctx->buf + num, inp, len);
77             ctx->num += len;
78             return 1;
79         }
80         /*
81          * We have enough data to fill or overflow the intermediate
82          * buffer. So we append |rem| bytes and process the block,
83          * leaving the rest for later processing...
84          */
85         memcpy(ctx->buf + num, inp, rem);
86         inp += rem, len -= rem;
87         (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
88         ctx->num = 0;
89         /* ctx->buf is processed, ctx->num is guaranteed to be zero */
90     }
91
92     if (len >= bsz)
93         rem = SHA3_absorb(ctx->A, inp, len, bsz);
94     else
95         rem = len;
96
97     if (rem) {
98         memcpy(ctx->buf, inp + len - rem, rem);
99         ctx->num = rem;
100     }
101
102     return 1;
103 }
104
105 static int sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
106 {
107     KECCAK1600_CTX *ctx = evp_ctx->md_data;
108     size_t bsz = ctx->block_size;
109     size_t num = ctx->num;
110
111     /*
112      * Pad the data with 10*1. Note that |num| can be |bsz - 1|
113      * in which case both byte operations below are performed on
114      * same byte...
115      */
116     memset(ctx->buf + num, 0, bsz - num);
117     ctx->buf[num] = ctx->pad;
118     ctx->buf[bsz - 1] |= 0x80;
119
120     (void)SHA3_absorb(ctx->A, ctx->buf, bsz, bsz);
121
122     SHA3_squeeze(ctx->A, md, ctx->md_size, bsz);
123
124     return 1;
125 }
126
127 static int shake_ctrl(EVP_MD_CTX *evp_ctx, int cmd, int p1, void *p2)
128 {
129     KECCAK1600_CTX *ctx = evp_ctx->md_data;
130
131     switch (cmd) {
132     case EVP_MD_CTRL_XOF_LEN:
133         ctx->md_size = p1;
134         return 1;
135     default:
136         return 0;
137     }
138 }
139
140 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) && defined(KECCAK1600_ASM)
141 /*
142  * IBM S390X support
143  */
144 # include "s390x_arch.h"
145
146 # define S390X_SHA3_FC(ctx)     ((ctx)->pad)
147
148 # define S390X_sha3_224_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
149                                   S390X_CAPBIT(S390X_SHA3_224)) &&  \
150                                  (OPENSSL_s390xcap_P.klmd[0] &      \
151                                   S390X_CAPBIT(S390X_SHA3_224)))
152 # define S390X_sha3_256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
153                                   S390X_CAPBIT(S390X_SHA3_256)) &&  \
154                                  (OPENSSL_s390xcap_P.klmd[0] &      \
155                                   S390X_CAPBIT(S390X_SHA3_256)))
156 # define S390X_sha3_384_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
157                                   S390X_CAPBIT(S390X_SHA3_384)) &&  \
158                                  (OPENSSL_s390xcap_P.klmd[0] &      \
159                                   S390X_CAPBIT(S390X_SHA3_384)))
160 # define S390X_sha3_512_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
161                                   S390X_CAPBIT(S390X_SHA3_512)) &&  \
162                                  (OPENSSL_s390xcap_P.klmd[0] &      \
163                                   S390X_CAPBIT(S390X_SHA3_512)))
164 # define S390X_shake128_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
165                                   S390X_CAPBIT(S390X_SHAKE_128)) && \
166                                  (OPENSSL_s390xcap_P.klmd[0] &      \
167                                   S390X_CAPBIT(S390X_SHAKE_128)))
168 # define S390X_shake256_CAPABLE ((OPENSSL_s390xcap_P.kimd[0] &      \
169                                   S390X_CAPBIT(S390X_SHAKE_256)) && \
170                                  (OPENSSL_s390xcap_P.klmd[0] &      \
171                                   S390X_CAPBIT(S390X_SHAKE_256)))
172
173 /* Convert md-size to block-size. */
174 # define S390X_KECCAK1600_BSZ(n) ((KECCAK1600_WIDTH - ((n) << 1)) >> 3)
175
176 static int s390x_sha3_init(EVP_MD_CTX *evp_ctx)
177 {
178     KECCAK1600_CTX *ctx = evp_ctx->md_data;
179     const size_t bsz = evp_ctx->digest->block_size;
180
181     /*-
182      * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
183      * function code.
184      */
185     switch (bsz) {
186     case S390X_KECCAK1600_BSZ(224):
187         ctx->pad = S390X_SHA3_224;
188         break;
189     case S390X_KECCAK1600_BSZ(256):
190         ctx->pad = S390X_SHA3_256;
191         break;
192     case S390X_KECCAK1600_BSZ(384):
193         ctx->pad = S390X_SHA3_384;
194         break;
195     case S390X_KECCAK1600_BSZ(512):
196         ctx->pad = S390X_SHA3_512;
197         break;
198     default:
199         return 0;
200     }
201
202     memset(ctx->A, 0, sizeof(ctx->A));
203     ctx->num = 0;
204     ctx->block_size = bsz;
205     ctx->md_size = evp_ctx->digest->md_size;
206     return 1;
207 }
208
209 static int s390x_shake_init(EVP_MD_CTX *evp_ctx)
210 {
211     KECCAK1600_CTX *ctx = evp_ctx->md_data;
212     const size_t bsz = evp_ctx->digest->block_size;
213
214     /*-
215      * KECCAK1600_CTX structure's pad field is used to store the KIMD/KLMD
216      * function code.
217      */
218     switch (bsz) {
219     case S390X_KECCAK1600_BSZ(128):
220         ctx->pad = S390X_SHAKE_128;
221         break;
222     case S390X_KECCAK1600_BSZ(256):
223         ctx->pad = S390X_SHAKE_256;
224         break;
225     default:
226         return 0;
227     }
228
229     memset(ctx->A, 0, sizeof(ctx->A));
230     ctx->num = 0;
231     ctx->block_size = bsz;
232     ctx->md_size = evp_ctx->digest->md_size;
233     return 1;
234 }
235
236 static int s390x_sha3_update(EVP_MD_CTX *evp_ctx, const void *_inp, size_t len)
237 {
238     KECCAK1600_CTX *ctx = evp_ctx->md_data;
239     const unsigned char *inp = _inp;
240     const size_t bsz = ctx->block_size;
241     size_t num, rem;
242
243     if (len == 0)
244         return 1;
245
246     if ((num = ctx->num) != 0) {
247         rem = bsz - num;
248
249         if (len < rem) {
250             memcpy(ctx->buf + num, inp, len);
251             ctx->num += len;
252             return 1;
253         }
254         memcpy(ctx->buf + num, inp, rem);
255         inp += rem;
256         len -= rem;
257         s390x_kimd(ctx->buf, bsz, ctx->pad, ctx->A);
258         ctx->num = 0;
259     }
260     rem = len % bsz;
261
262     s390x_kimd(inp, len - rem, ctx->pad, ctx->A);
263
264     if (rem) {
265         memcpy(ctx->buf, inp + len - rem, rem);
266         ctx->num = rem;
267     }
268     return 1;
269 }
270
271 static int s390x_sha3_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
272 {
273     KECCAK1600_CTX *ctx = evp_ctx->md_data;
274
275     s390x_klmd(ctx->buf, ctx->num, NULL, 0, ctx->pad, ctx->A);
276     memcpy(md, ctx->A, ctx->md_size);
277     return 1;
278 }
279
280 static int s390x_shake_final(EVP_MD_CTX *evp_ctx, unsigned char *md)
281 {
282     KECCAK1600_CTX *ctx = evp_ctx->md_data;
283
284     s390x_klmd(ctx->buf, ctx->num, md, ctx->md_size, ctx->pad, ctx->A);
285     return 1;
286 }
287
288 # define EVP_MD_SHA3(bitlen)                         \
289 const EVP_MD *EVP_sha3_##bitlen(void)                \
290 {                                                    \
291     static const EVP_MD s390x_sha3_##bitlen##_md = { \
292         NID_sha3_##bitlen,                           \
293         NID_RSA_SHA3_##bitlen,                       \
294         bitlen / 8,                                  \
295         EVP_MD_FLAG_DIGALGID_ABSENT,                 \
296         s390x_sha3_init,                             \
297         s390x_sha3_update,                           \
298         s390x_sha3_final,                            \
299         NULL,                                        \
300         NULL,                                        \
301         (KECCAK1600_WIDTH - bitlen * 2) / 8,         \
302         sizeof(KECCAK1600_CTX),                      \
303     };                                               \
304     static const EVP_MD sha3_##bitlen##_md = {       \
305         NID_sha3_##bitlen,                           \
306         NID_RSA_SHA3_##bitlen,                       \
307         bitlen / 8,                                  \
308         EVP_MD_FLAG_DIGALGID_ABSENT,                 \
309         sha3_init,                                   \
310         sha3_update,                                 \
311         sha3_final,                                  \
312         NULL,                                        \
313         NULL,                                        \
314         (KECCAK1600_WIDTH - bitlen * 2) / 8,         \
315         sizeof(KECCAK1600_CTX),                      \
316     };                                               \
317     return S390X_sha3_##bitlen##_CAPABLE ?           \
318            &s390x_sha3_##bitlen##_md :               \
319            &sha3_##bitlen##_md;                      \
320 }
321
322 # define EVP_MD_SHAKE(bitlen)                        \
323 const EVP_MD *EVP_shake##bitlen(void)                \
324 {                                                    \
325     static const EVP_MD s390x_shake##bitlen##_md = { \
326         NID_shake##bitlen,                           \
327         0,                                           \
328         bitlen / 8,                                  \
329         EVP_MD_FLAG_XOF,                             \
330         s390x_shake_init,                            \
331         s390x_sha3_update,                           \
332         s390x_shake_final,                           \
333         NULL,                                        \
334         NULL,                                        \
335         (KECCAK1600_WIDTH - bitlen * 2) / 8,         \
336         sizeof(KECCAK1600_CTX),                      \
337         shake_ctrl                                   \
338     };                                               \
339     static const EVP_MD shake##bitlen##_md = {       \
340         NID_shake##bitlen,                           \
341         0,                                           \
342         bitlen / 8,                                  \
343         EVP_MD_FLAG_XOF,                             \
344         shake_init,                                  \
345         sha3_update,                                 \
346         sha3_final,                                  \
347         NULL,                                        \
348         NULL,                                        \
349         (KECCAK1600_WIDTH - bitlen * 2) / 8,         \
350         sizeof(KECCAK1600_CTX),                      \
351         shake_ctrl                                   \
352     };                                               \
353     return S390X_shake##bitlen##_CAPABLE ?           \
354            &s390x_shake##bitlen##_md :               \
355            &shake##bitlen##_md;                      \
356 }
357
358 #else
359
360 # define EVP_MD_SHA3(bitlen)                    \
361 const EVP_MD *EVP_sha3_##bitlen(void)           \
362 {                                               \
363     static const EVP_MD sha3_##bitlen##_md = {  \
364         NID_sha3_##bitlen,                      \
365         NID_RSA_SHA3_##bitlen,                  \
366         bitlen / 8,                             \
367         EVP_MD_FLAG_DIGALGID_ABSENT,            \
368         sha3_init,                              \
369         sha3_update,                            \
370         sha3_final,                             \
371         NULL,                                   \
372         NULL,                                   \
373         (KECCAK1600_WIDTH - bitlen * 2) / 8,    \
374         sizeof(KECCAK1600_CTX),                 \
375     };                                          \
376     return &sha3_##bitlen##_md;                 \
377 }
378
379 # define EVP_MD_SHAKE(bitlen)                   \
380 const EVP_MD *EVP_shake##bitlen(void)           \
381 {                                               \
382     static const EVP_MD shake##bitlen##_md = {  \
383         NID_shake##bitlen,                      \
384         0,                                      \
385         bitlen / 8,                             \
386         EVP_MD_FLAG_XOF,                        \
387         shake_init,                             \
388         sha3_update,                            \
389         sha3_final,                             \
390         NULL,                                   \
391         NULL,                                   \
392         (KECCAK1600_WIDTH - bitlen * 2) / 8,    \
393         sizeof(KECCAK1600_CTX),                 \
394         shake_ctrl                              \
395     };                                          \
396     return &shake##bitlen##_md;                 \
397 }
398 #endif
399
400 EVP_MD_SHA3(224)
401 EVP_MD_SHA3(256)
402 EVP_MD_SHA3(384)
403 EVP_MD_SHA3(512)
404
405 EVP_MD_SHAKE(128)
406 EVP_MD_SHAKE(256)