/ ltc-digests.c
ltc-digests.c
  1  /*
  2   * Licensed under the Apache License, Version 2.0 (the "License");
  3   * you may not use this file except in compliance with the License.
  4   * See the NOTICE file distributed with this work for additional
  5   * information regarding copyright ownership.
  6   * You may obtain a copy of the License at
  7   *
  8   *     http://www.apache.org/licenses/LICENSE-2.0
  9   *
 10   * Unless required by applicable law or agreed to in writing, software
 11   * distributed under the License is distributed on an "AS IS" BASIS,
 12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13   * See the License for the specific language governing permissions and
 14   * limitations under the License.
 15   */
 16  
 17  #include <tomcrypt.h>
 18  #include <lsplugin/mkoperator.h>
 19  
 20  struct digest_state_st {
 21    hash_state libtomcrypt_data;
 22    const struct ltc_hash_descriptor *libtomcrypt_desc;
 23  };
 24  
 25  static LE_STATUS
 26  setup_digest_data(LSC_digester_t *d)
 27  {
 28    assert(d != NULL && d->lsc_dispatch_data != NULL);
 29  
 30    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
 31    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
 32    struct digest_state_st **state = (struct digest_state_st **)&d->lsc_data;
 33  
 34    if (*state == NULL) {
 35      *state = malloc(sizeof(**state));
 36      memset(*state, 0, sizeof(**state));
 37  
 38      (*state)->libtomcrypt_desc = ltc_desc;
 39    }
 40    if (*state == NULL)
 41      return LE_STS_FATAL_ERROR;
 42  
 43    assert((*state)->libtomcrypt_desc == ltc_desc);
 44  
 45    return LE_STS_SUCCESS;
 46  }
 47  
 48  static LE_STATUS clean_digest_data(LSC_digester_t *d)
 49  {
 50    assert(d != NULL && d->lsc_data != NULL);
 51  
 52    struct digest_state_st **state = (struct digest_state_st **)&d->lsc_data;
 53  
 54    if (*state != NULL) {
 55      (*state)->libtomcrypt_desc = NULL;
 56  
 57      free(*state);
 58      *state = NULL;
 59    }
 60  
 61    return LE_STS_SUCCESS;    /* Not yet implemented */
 62  }
 63  
 64  static LE_STATUS get_digest_input_size(LSC_digester_t *d, size_t *size)
 65  {
 66    assert(size != NULL);
 67  
 68    /*
 69     * This means infinite.  It should be noted, though, that libtomcrypt's
 70     * manual has a footnote in the "One-Way Cryptographic Hash Functions -
 71     * Core Functions" section saying this:
 72     *
 73     *     Most hashes are limited to 2^64 bits or 2,305,843,009,213,693,952
 74     *     bytes.
 75     *
 76     * However, such a number is not practical to parametrise (among others
 77     * because it's such a large number), so we might as well go with the
 78     * "virtually infinitly long messages" that the same manual page tells
 79     * us.
 80     */
 81    *size = 0;
 82    return LE_STS_SUCCESS;
 83  }
 84  
 85  static LE_STATUS get_digest_size(LSC_digester_t *d, size_t *size)
 86  {
 87    assert(d != NULL && d->lsc_dispatch_data != NULL);
 88    assert(size != NULL);
 89  
 90    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
 91    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
 92    assert(ltc_desc != NULL);
 93    *size = (size_t)ltc_desc->hashsize;
 94    return LE_STS_SUCCESS;
 95  }
 96  
 97  static LE_STATUS perform_digest_once(LSC_digester_t *d,
 98                                       const unsigned char *msg,
 99                                       size_t msglen,
100                                       unsigned char *digest,
101                                       size_t digestsize,
102                                       size_t *digestlen)
103  {
104    assert(d != NULL && d->lsc_dispatch_data != NULL);
105    assert(msg != NULL);
106  
107    LE_STATUS sts = setup_digest_data(d);
108    if (!LE_status_is_OK(sts))
109      return sts;
110  
111    assert(d->lsc_data != NULL);
112  
113    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
114    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
115    struct digest_state_st *state = d->lsc_data;
116    assert(ltc_desc != NULL);
117  
118    if (digestlen != NULL)
119      *digestlen = ltc_desc->hashsize;
120    if (digestsize < ltc_desc->hashsize)
121      return LE_STS_ERROR;
122    if (ltc_desc->init(&state->libtomcrypt_data) != CRYPT_OK)
123      return LE_STS_ERROR;
124    if (ltc_desc->process(&state->libtomcrypt_data, msg, msglen) != CRYPT_OK)
125      return LE_STS_ERROR;
126    if (ltc_desc->done(&state->libtomcrypt_data, digest) != CRYPT_OK)
127      return LE_STS_ERROR;
128    return LE_STS_SUCCESS;
129  }
130  
131  static LE_STATUS start_digest(LSC_digester_t *d)
132  {
133    assert(d != NULL && d->lsc_dispatch_data != NULL);
134  
135    LE_STATUS sts = setup_digest_data(d);
136    if (!LE_status_is_OK(sts))
137      return sts;
138  
139    assert(d->lsc_data != NULL);
140  
141    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
142    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
143    struct digest_state_st *state = d->lsc_data;
144    assert(ltc_desc != NULL);
145  
146    if (ltc_desc->init(&state->libtomcrypt_data) != CRYPT_OK)
147      return LE_STS_ERROR;
148    return LE_STS_SUCCESS;
149  }
150  
151  static LE_STATUS accumulate_digest_input(LSC_digester_t *d,
152                                           const unsigned char *msg,
153                                           size_t msglen)
154  {
155    assert(d != NULL && d->lsc_dispatch_data != NULL);
156    assert(d->lsc_data != NULL);
157    assert(msg != NULL);
158  
159    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
160    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
161    struct digest_state_st *state = d->lsc_data;
162    assert(ltc_desc != NULL);
163  
164    if (ltc_desc->process(&state->libtomcrypt_data, msg, msglen) != CRYPT_OK)
165      return LE_STS_ERROR;
166    return LE_STS_SUCCESS;
167  }
168  
169  #define extract_digest_output NULL
170  static LE_STATUS finalize_digest(LSC_digester_t *d,
171                                   unsigned char *digest,
172                                   size_t digestsize,
173                                   size_t *digestlen)
174  {
175    assert(d != NULL && d->lsc_dispatch_data != NULL);
176    assert(d->lsc_data != NULL);
177  
178    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
179    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
180    struct digest_state_st *state = d->lsc_data;
181    assert(ltc_desc != NULL);
182  
183    if (digestlen != NULL)
184      *digestlen = ltc_desc->hashsize;
185    if (digestsize < ltc_desc->hashsize)
186      return LE_STS_ERROR;
187    if (ltc_desc->done(&state->libtomcrypt_data, digest) != CRYPT_OK)
188      return LE_STS_ERROR;
189    return LE_STS_SUCCESS;
190  }
191  
192  static LE_STATUS stop_digest(LSC_digester_t *d)
193  {
194    assert(d != NULL && d->lsc_dispatch_data != NULL);
195    assert(d->lsc_data != NULL);
196  
197    const LSplugin_digester_desc_t *desc = d->lsc_dispatch_data;
198    const struct ltc_hash_descriptor *ltc_desc = desc->lsp_priv_desc;
199    struct digest_state_st *state = d->lsc_data;
200    assert(ltc_desc != NULL);
201  
202    /* This is just a precaution, in case the finalize function wasn't called */
203    unsigned char buf[ltc_desc->hashsize];
204    if (ltc_desc->done(&state->libtomcrypt_data, buf) != CRYPT_OK)
205      return LE_STS_ERROR;
206    return LE_STS_SUCCESS;
207  }
208  
209  #define setup_whirlpool_data setup_digest_data
210  #define clean_whirlpool_data clean_digest_data
211  #define get_whirlpool_input_size get_digest_input_size
212  #define get_whirlpool_size get_digest_size
213  #define perform_whirlpool_once perform_digest_once
214  #define start_whirlpool start_digest
215  #define accumulate_whirlpool_input accumulate_digest_input
216  #define extract_whirlpool_output extract_digest_output
217  #define finalize_whirlpool finalize_digest
218  #define stop_whirlpool stop_digest
219  
220  #define setup_sha3_512_data setup_digest_data
221  #define clean_sha3_512_data clean_digest_data
222  #define get_sha3_512_input_size get_digest_input_size
223  #define get_sha3_512_size get_digest_size
224  #define perform_sha3_512_once perform_digest_once
225  #define start_sha3_512 start_digest
226  #define accumulate_sha3_512_input accumulate_digest_input
227  #define extract_sha3_512_output extract_digest_output
228  #define finalize_sha3_512 finalize_digest
229  #define stop_sha3_512 stop_digest
230  
231  #define setup_sha512_data setup_digest_data
232  #define clean_sha512_data clean_digest_data
233  #define get_sha512_input_size get_digest_input_size
234  #define get_sha512_size get_digest_size
235  #define perform_sha512_once perform_digest_once
236  #define start_sha512 start_digest
237  #define accumulate_sha512_input accumulate_digest_input
238  #define extract_sha512_output extract_digest_output
239  #define finalize_sha512 finalize_digest
240  #define stop_sha512 stop_digest
241  
242  #define setup_blake2b_512_data setup_digest_data
243  #define clean_blake2b_512_data clean_digest_data
244  #define get_blake2b_512_input_size get_digest_input_size
245  #define get_blake2b_512_size get_digest_size
246  #define perform_blake2b_512_once perform_digest_once
247  #define start_blake2b_512 start_digest
248  #define accumulate_blake2b_512_input accumulate_digest_input
249  #define extract_blake2b_512_output extract_digest_output
250  #define finalize_blake2b_512 finalize_digest
251  #define stop_blake2b_512 stop_digest
252  
253  #define setup_sha3_384_data setup_digest_data
254  #define clean_sha3_384_data clean_digest_data
255  #define get_sha3_384_input_size get_digest_input_size
256  #define get_sha3_384_size get_digest_size
257  #define perform_sha3_384_once perform_digest_once
258  #define start_sha3_384 start_digest
259  #define accumulate_sha3_384_input accumulate_digest_input
260  #define extract_sha3_384_output extract_digest_output
261  #define finalize_sha3_384 finalize_digest
262  #define stop_sha3_384 stop_digest
263  
264  #define setup_sha384_data setup_digest_data
265  #define clean_sha384_data clean_digest_data
266  #define get_sha384_input_size get_digest_input_size
267  #define get_sha384_size get_digest_size
268  #define perform_sha384_once perform_digest_once
269  #define start_sha384 start_digest
270  #define accumulate_sha384_input accumulate_digest_input
271  #define extract_sha384_output extract_digest_output
272  #define finalize_sha384 finalize_digest
273  #define stop_sha384 stop_digest
274  
275  #define setup_rmd320_data setup_digest_data
276  #define clean_rmd320_data clean_digest_data
277  #define get_rmd320_input_size get_digest_input_size
278  #define get_rmd320_size get_digest_size
279  #define perform_rmd320_once perform_digest_once
280  #define start_rmd320 start_digest
281  #define accumulate_rmd320_input accumulate_digest_input
282  #define extract_rmd320_output extract_digest_output
283  #define finalize_rmd320 finalize_digest
284  #define stop_rmd320 stop_digest
285  
286  #define setup_sha512_256_data setup_digest_data
287  #define clean_sha512_256_data clean_digest_data
288  #define get_sha512_256_input_size get_digest_input_size
289  #define get_sha512_256_size get_digest_size
290  #define perform_sha512_256_once perform_digest_once
291  #define start_sha512_256 start_digest
292  #define accumulate_sha512_256_input accumulate_digest_input
293  #define extract_sha512_256_output extract_digest_output
294  #define finalize_sha512_256 finalize_digest
295  #define stop_sha512_256 stop_digest
296  
297  #define setup_sha3_256_data setup_digest_data
298  #define clean_sha3_256_data clean_digest_data
299  #define get_sha3_256_input_size get_digest_input_size
300  #define get_sha3_256_size get_digest_size
301  #define perform_sha3_256_once perform_digest_once
302  #define start_sha3_256 start_digest
303  #define accumulate_sha3_256_input accumulate_digest_input
304  #define extract_sha3_256_output extract_digest_output
305  #define finalize_sha3_256 finalize_digest
306  #define stop_sha3_256 stop_digest
307  
308  #define setup_sha256_data setup_digest_data
309  #define clean_sha256_data clean_digest_data
310  #define get_sha256_input_size get_digest_input_size
311  #define get_sha256_size get_digest_size
312  #define perform_sha256_once perform_digest_once
313  #define start_sha256 start_digest
314  #define accumulate_sha256_input accumulate_digest_input
315  #define extract_sha256_output extract_digest_output
316  #define finalize_sha256 finalize_digest
317  #define stop_sha256 stop_digest
318  
319  #define setup_rmd256_data setup_digest_data
320  #define clean_rmd256_data clean_digest_data
321  #define get_rmd256_input_size get_digest_input_size
322  #define get_rmd256_size get_digest_size
323  #define perform_rmd256_once perform_digest_once
324  #define start_rmd256 start_digest
325  #define accumulate_rmd256_input accumulate_digest_input
326  #define extract_rmd256_output extract_digest_output
327  #define finalize_rmd256 finalize_digest
328  #define stop_rmd256 stop_digest
329  
330  #define setup_blake2s_256_data setup_digest_data
331  #define clean_blake2s_256_data clean_digest_data
332  #define get_blake2s_256_input_size get_digest_input_size
333  #define get_blake2s_256_size get_digest_size
334  #define perform_blake2s_256_once perform_digest_once
335  #define start_blake2s_256 start_digest
336  #define accumulate_blake2s_256_input accumulate_digest_input
337  #define extract_blake2s_256_output extract_digest_output
338  #define finalize_blake2s_256 finalize_digest
339  #define stop_blake2s_256 stop_digest
340  
341  #define setup_blake2b_256_data setup_digest_data
342  #define clean_blake2b_256_data clean_digest_data
343  #define get_blake2b_256_input_size get_digest_input_size
344  #define get_blake2b_256_size get_digest_size
345  #define perform_blake2b_256_once perform_digest_once
346  #define start_blake2b_256 start_digest
347  #define accumulate_blake2b_256_input accumulate_digest_input
348  #define extract_blake2b_256_output extract_digest_output
349  #define finalize_blake2b_256 finalize_digest
350  #define stop_blake2b_256 stop_digest
351  
352  #define setup_sha512_224_data setup_digest_data
353  #define clean_sha512_224_data clean_digest_data
354  #define get_sha512_224_input_size get_digest_input_size
355  #define get_sha512_224_size get_digest_size
356  #define perform_sha512_224_once perform_digest_once
357  #define start_sha512_224 start_digest
358  #define accumulate_sha512_224_input accumulate_digest_input
359  #define extract_sha512_224_output extract_digest_output
360  #define finalize_sha512_224 finalize_digest
361  #define stop_sha512_224 stop_digest
362  
363  #define setup_sha3_224_data setup_digest_data
364  #define clean_sha3_224_data clean_digest_data
365  #define get_sha3_224_input_size get_digest_input_size
366  #define get_sha3_224_size get_digest_size
367  #define perform_sha3_224_once perform_digest_once
368  #define start_sha3_224 start_digest
369  #define accumulate_sha3_224_input accumulate_digest_input
370  #define extract_sha3_224_output extract_digest_output
371  #define finalize_sha3_224 finalize_digest
372  #define stop_sha3_224 stop_digest
373  
374  #define setup_sha224_data setup_digest_data
375  #define clean_sha224_data clean_digest_data
376  #define get_sha224_input_size get_digest_input_size
377  #define get_sha224_size get_digest_size
378  #define perform_sha224_once perform_digest_once
379  #define start_sha224 start_digest
380  #define accumulate_sha224_input accumulate_digest_input
381  #define extract_sha224_output extract_digest_output
382  #define finalize_sha224 finalize_digest
383  #define stop_sha224 stop_digest
384  
385  #define setup_blake2s_224_data setup_digest_data
386  #define clean_blake2s_224_data clean_digest_data
387  #define get_blake2s_224_input_size get_digest_input_size
388  #define get_blake2s_224_size get_digest_size
389  #define perform_blake2s_224_once perform_digest_once
390  #define start_blake2s_224 start_digest
391  #define accumulate_blake2s_224_input accumulate_digest_input
392  #define extract_blake2s_224_output extract_digest_output
393  #define finalize_blake2s_224 finalize_digest
394  #define stop_blake2s_224 stop_digest
395  
396  #define setup_blake2b_384_data setup_digest_data
397  #define clean_blake2b_384_data clean_digest_data
398  #define get_blake2b_384_input_size get_digest_input_size
399  #define get_blake2b_384_size get_digest_size
400  #define perform_blake2b_384_once perform_digest_once
401  #define start_blake2b_384 start_digest
402  #define accumulate_blake2b_384_input accumulate_digest_input
403  #define extract_blake2b_384_output extract_digest_output
404  #define finalize_blake2b_384 finalize_digest
405  #define stop_blake2b_384 stop_digest
406  
407  #define setup_tiger_data setup_digest_data
408  #define clean_tiger_data clean_digest_data
409  #define get_tiger_input_size get_digest_input_size
410  #define get_tiger_size get_digest_size
411  #define perform_tiger_once perform_digest_once
412  #define start_tiger start_digest
413  #define accumulate_tiger_input accumulate_digest_input
414  #define extract_tiger_output extract_digest_output
415  #define finalize_tiger finalize_digest
416  #define stop_tiger stop_digest
417  
418  #define setup_sha1_data setup_digest_data
419  #define clean_sha1_data clean_digest_data
420  #define get_sha1_input_size get_digest_input_size
421  #define get_sha1_size get_digest_size
422  #define perform_sha1_once perform_digest_once
423  #define start_sha1 start_digest
424  #define accumulate_sha1_input accumulate_digest_input
425  #define extract_sha1_output extract_digest_output
426  #define finalize_sha1 finalize_digest
427  #define stop_sha1 stop_digest
428  
429  #define setup_rmd160_data setup_digest_data
430  #define clean_rmd160_data clean_digest_data
431  #define get_rmd160_input_size get_digest_input_size
432  #define get_rmd160_size get_digest_size
433  #define perform_rmd160_once perform_digest_once
434  #define start_rmd160 start_digest
435  #define accumulate_rmd160_input accumulate_digest_input
436  #define extract_rmd160_output extract_digest_output
437  #define finalize_rmd160 finalize_digest
438  #define stop_rmd160 stop_digest
439  
440  #define setup_blake2s_160_data setup_digest_data
441  #define clean_blake2s_160_data clean_digest_data
442  #define get_blake2s_160_input_size get_digest_input_size
443  #define get_blake2s_160_size get_digest_size
444  #define perform_blake2s_160_once perform_digest_once
445  #define start_blake2s_160 start_digest
446  #define accumulate_blake2s_160_input accumulate_digest_input
447  #define extract_blake2s_160_output extract_digest_output
448  #define finalize_blake2s_160 finalize_digest
449  #define stop_blake2s_160 stop_digest
450  
451  #define setup_blake2b_160_data setup_digest_data
452  #define clean_blake2b_160_data clean_digest_data
453  #define get_blake2b_160_input_size get_digest_input_size
454  #define get_blake2b_160_size get_digest_size
455  #define perform_blake2b_160_once perform_digest_once
456  #define start_blake2b_160 start_digest
457  #define accumulate_blake2b_160_input accumulate_digest_input
458  #define extract_blake2b_160_output extract_digest_output
459  #define finalize_blake2b_160 finalize_digest
460  #define stop_blake2b_160 stop_digest
461  
462  #define setup_rmd128_data setup_digest_data
463  #define clean_rmd128_data clean_digest_data
464  #define get_rmd128_input_size get_digest_input_size
465  #define get_rmd128_size get_digest_size
466  #define perform_rmd128_once perform_digest_once
467  #define start_rmd128 start_digest
468  #define accumulate_rmd128_input accumulate_digest_input
469  #define extract_rmd128_output extract_digest_output
470  #define finalize_rmd128 finalize_digest
471  #define stop_rmd128 stop_digest
472  
473  #define setup_md5_data setup_digest_data
474  #define clean_md5_data clean_digest_data
475  #define get_md5_input_size get_digest_input_size
476  #define get_md5_size get_digest_size
477  #define perform_md5_once perform_digest_once
478  #define start_md5 start_digest
479  #define accumulate_md5_input accumulate_digest_input
480  #define extract_md5_output extract_digest_output
481  #define finalize_md5 finalize_digest
482  #define stop_md5 stop_digest
483  
484  #define setup_md4_data setup_digest_data
485  #define clean_md4_data clean_digest_data
486  #define get_md4_input_size get_digest_input_size
487  #define get_md4_size get_digest_size
488  #define perform_md4_once perform_digest_once
489  #define start_md4 start_digest
490  #define accumulate_md4_input accumulate_digest_input
491  #define extract_md4_output extract_digest_output
492  #define finalize_md4 finalize_digest
493  #define stop_md4 stop_digest
494  
495  #define setup_md2_data setup_digest_data
496  #define clean_md2_data clean_digest_data
497  #define get_md2_input_size get_digest_input_size
498  #define get_md2_size get_digest_size
499  #define perform_md2_once perform_digest_once
500  #define start_md2 start_digest
501  #define accumulate_md2_input accumulate_digest_input
502  #define extract_md2_output extract_digest_output
503  #define finalize_md2 finalize_digest
504  #define stop_md2 stop_digest
505  
506  #define setup_blake2s_128_data setup_digest_data
507  #define clean_blake2s_128_data clean_digest_data
508  #define get_blake2s_128_input_size get_digest_input_size
509  #define get_blake2s_128_size get_digest_size
510  #define perform_blake2s_128_once perform_digest_once
511  #define start_blake2s_128 start_digest
512  #define accumulate_blake2s_128_input accumulate_digest_input
513  #define extract_blake2s_128_output extract_digest_output
514  #define finalize_blake2s_128 finalize_digest
515  #define stop_blake2s_128 stop_digest
516  
517  /* The SHAKE implementations use libtomcrypt's hash_state directly */
518  
519  static struct { int i; } fake_desc;
520  #define shake128_desc fake_desc
521  #define shake256_desc fake_desc
522  
523  static LE_STATUS
524  setup_shake_data(LSC_digester_t *d)
525  {
526    assert(d != NULL);
527  
528    hash_state **state = (hash_state **)&d->lsc_data;
529  
530    if (*state == NULL) {
531      *state = malloc(sizeof(**state));
532      memset(*state, 0, sizeof(**state));
533    }
534    if (*state == NULL)
535      return LE_STS_FATAL_ERROR;
536    return LE_STS_SUCCESS;
537  }
538  #define setup_shake128_data setup_shake_data
539  #define setup_shake256_data setup_shake_data
540  
541  static LE_STATUS clean_shake_data(LSC_digester_t *d)
542  {
543    assert(d != NULL && d->lsc_data != NULL);
544  
545    hash_state **state = (hash_state **)&d->lsc_data;
546  
547    if (*state != NULL) {
548      free(*state);
549      *state = NULL;
550    }
551  
552    return LE_STS_SUCCESS;    /* Not yet implemented */
553  }
554  #define clean_shake128_data clean_shake_data
555  #define clean_shake256_data clean_shake_data
556  
557  static LE_STATUS get_shake_input_size(LSC_digester_t *d, size_t *size)
558  {
559    assert(size != NULL);
560  
561    /*
562     * This means infinite.  It should be noted, though, that libtomcrypt's
563     * manual has a footnote in the "One-Way Cryptographic Hash Functions -
564     * Core Functions" section saying this:
565     *
566     *     Most hashes are limited to 2^64 bits or 2,305,843,009,213,693,952
567     *     bytes.
568     *
569     * However, such a number is not practical to parametrise (among others
570     * because it's such a large number), so we might as well go with the
571     * "virtually infinitly long messages" that the same manual page tells
572     * us.
573     */
574    *size = 0;
575    return LE_STS_SUCCESS;
576  }
577  #define get_shake128_input_size get_shake_input_size
578  #define get_shake256_input_size get_shake_input_size
579  
580  static LE_STATUS get_shake_size(LSC_digester_t *d, size_t *size)
581  {
582    assert(size != NULL);
583  
584    /*
585     * This means infinite.  That's a special property of Squeeze type hash
586     * extraction.
587     */
588    *size = 0;
589    return LE_STS_SUCCESS;
590  }
591  #define get_shake128_size get_shake_size
592  #define get_shake256_size get_shake_size
593  
594  #define perform_shake128_once NULL
595  #define perform_shake256_once NULL
596  
597  static LE_STATUS start_shake(LSC_digester_t *d, int bits)
598  {
599    assert(d != NULL);
600  
601    LE_STATUS sts = setup_digest_data(d);
602    if (!LE_status_is_OK(sts))
603      return sts;
604  
605    assert(d->lsc_data != NULL);
606  
607    hash_state *state = d->lsc_data;
608  
609    if (sha3_shake_init(state, bits) != CRYPT_OK)
610      return LE_STS_ERROR;
611    return LE_STS_SUCCESS;
612  }
613  static LE_STATUS start_shake128(LSC_digester_t *d)
614  {
615    return start_shake(d, 128);
616  }
617  static LE_STATUS start_shake256(LSC_digester_t *d)
618  {
619    return start_shake(d, 256);
620  }
621  
622  static LE_STATUS accumulate_shake_input(LSC_digester_t *d,
623                                          const unsigned char *msg,
624                                          size_t msglen)
625  {
626    assert(d != NULL);
627    assert(d->lsc_data != NULL);
628    assert(msg != NULL);
629  
630    hash_state *state = d->lsc_data;
631    assert(state != NULL);
632  
633    if (sha3_shake_process(state, msg, msglen) != CRYPT_OK)
634      return LE_STS_ERROR;
635    return LE_STS_SUCCESS;
636  }
637  #define accumulate_shake128_input accumulate_shake_input
638  #define accumulate_shake256_input accumulate_shake_input
639  
640  static LE_STATUS extract_shake_output(LSC_digester_t *d,
641                                        unsigned char *out,
642                                        size_t outsize,
643                                        size_t *outlen)
644  {
645    assert(d != NULL);
646    assert(d->lsc_data != NULL);
647  
648    hash_state *state = d->lsc_data;
649    assert(state != NULL);
650  
651    if (outlen != NULL)
652      *outlen = outsize;
653    if (out == NULL)
654      return LE_STS_ERROR;
655    if (sha3_shake_done(state, out, outsize) != CRYPT_OK)
656      return LE_STS_ERROR;
657    return LE_STS_SUCCESS;
658  }
659  #define extract_shake128_output extract_shake_output
660  #define extract_shake256_output extract_shake_output
661  
662  #define finalize_shake128 extract_shake_output
663  #define finalize_shake256 extract_shake_output
664  
665  static LE_STATUS stop_shake(LSC_digester_t *d)
666  {
667    assert(d != NULL);
668    assert(d->lsc_data != NULL);
669  
670    hash_state *state = d->lsc_data;
671  
672    /* This is just a precaution, in case the finalize function wasn't called */
673    unsigned char buf[32];
674    if (sha3_shake_done(state, buf, sizeof(buf)) != CRYPT_OK)
675      return LE_STS_ERROR;
676    return LE_STS_SUCCESS;
677  }
678  #define stop_shake128 stop_shake
679  #define stop_shake256 stop_shake
680  
681  #define IMPL_STD_CMDS()                         \
682    LSC_DIGESTER_TYPE_BASE_COMMANDS(),            \
683      LSC_DIGESTER_SIZE_COMMANDS(),               \
684      LSC_NR_start_digestion,                     \
685      LSC_NR_accumulate_digestion_input,          \
686      LSC_NR_finalize_digestion,                  \
687      LSC_NR_stop_digestion
688  #define IMPL_whirlpool_CMDS()                   \
689    IMPL_STD_CMDS(),                              \
690      LSC_NR_perform_digestion_once
691  #define IMPL_sha3_512_CMDS()                    \
692    IMPL_STD_CMDS(),                              \
693      LSC_NR_perform_digestion_once
694  #define IMPL_sha512_CMDS()                      \
695    IMPL_STD_CMDS(),                              \
696      LSC_NR_perform_digestion_once
697  #define IMPL_blake2b_512_CMDS()                 \
698    IMPL_STD_CMDS(),                              \
699      LSC_NR_perform_digestion_once
700  #define IMPL_sha3_384_CMDS()                    \
701    IMPL_STD_CMDS(),                              \
702      LSC_NR_perform_digestion_once
703  #define IMPL_sha384_CMDS()                      \
704    IMPL_STD_CMDS(),                              \
705      LSC_NR_perform_digestion_once
706  #define IMPL_rmd320_CMDS()                      \
707    IMPL_STD_CMDS(),                              \
708      LSC_NR_perform_digestion_once
709  #define IMPL_sha512_256_CMDS()                  \
710    IMPL_STD_CMDS(),                              \
711      LSC_NR_perform_digestion_once
712  #define IMPL_sha3_256_CMDS()                    \
713    IMPL_STD_CMDS(),                              \
714      LSC_NR_perform_digestion_once
715  #define IMPL_sha256_CMDS()                      \
716    IMPL_STD_CMDS(),                              \
717      LSC_NR_perform_digestion_once
718  #define IMPL_rmd256_CMDS()                      \
719    IMPL_STD_CMDS(),                              \
720      LSC_NR_perform_digestion_once
721  #define IMPL_blake2s_256_CMDS()                 \
722    IMPL_STD_CMDS(),                              \
723      LSC_NR_perform_digestion_once
724  #define IMPL_blake2b_256_CMDS()                 \
725    IMPL_STD_CMDS(),                              \
726      LSC_NR_perform_digestion_once
727  #define IMPL_sha512_224_CMDS()                  \
728    IMPL_STD_CMDS(),                              \
729      LSC_NR_perform_digestion_once
730  #define IMPL_sha3_224_CMDS()                    \
731    IMPL_STD_CMDS(),                              \
732      LSC_NR_perform_digestion_once
733  #define IMPL_sha224_CMDS()                      \
734    IMPL_STD_CMDS(),                              \
735      LSC_NR_perform_digestion_once
736  #define IMPL_blake2s_224_CMDS()                 \
737    IMPL_STD_CMDS(),                              \
738      LSC_NR_perform_digestion_once
739  #define IMPL_blake2b_384_CMDS()                 \
740    IMPL_STD_CMDS(),                              \
741      LSC_NR_perform_digestion_once
742  #define IMPL_tiger_CMDS()                       \
743    IMPL_STD_CMDS(),                              \
744      LSC_NR_perform_digestion_once
745  #define IMPL_sha1_CMDS()                        \
746    IMPL_STD_CMDS(),                              \
747      LSC_NR_perform_digestion_once
748  #define IMPL_rmd160_CMDS()                      \
749    IMPL_STD_CMDS(),                              \
750      LSC_NR_perform_digestion_once
751  #define IMPL_blake2s_160_CMDS()                 \
752    IMPL_STD_CMDS(),                              \
753      LSC_NR_perform_digestion_once
754  #define IMPL_blake2b_160_CMDS()                 \
755    IMPL_STD_CMDS(),                              \
756      LSC_NR_perform_digestion_once
757  #define IMPL_rmd128_CMDS()                      \
758    IMPL_STD_CMDS(),                              \
759      LSC_NR_perform_digestion_once
760  #define IMPL_md5_CMDS()                         \
761    IMPL_STD_CMDS(),                              \
762      LSC_NR_perform_digestion_once
763  #define IMPL_md4_CMDS()                         \
764    IMPL_STD_CMDS(),                              \
765      LSC_NR_perform_digestion_once
766  #define IMPL_md2_CMDS()                         \
767    IMPL_STD_CMDS(),                              \
768      LSC_NR_perform_digestion_once
769  #define IMPL_blake2s_128_CMDS()                 \
770    IMPL_STD_CMDS(),                              \
771      LSC_NR_perform_digestion_once
772  #define IMPL_shake128_CMDS()                    \
773    IMPL_STD_CMDS(),                              \
774      LSC_NR_extract_digestion_output
775  #define IMPL_shake256_CMDS()                    \
776    IMPL_STD_CMDS(),                              \
777      LSC_NR_extract_digestion_output
778  
779  #define IMPL_whirlpool_NAME()   "whirlpool"
780  #define IMPL_sha3_512_NAME()    "sha3-512"
781  #define IMPL_sha512_NAME()      "sha-512"
782  #define IMPL_blake2b_512_NAME() "blake2b-512"
783  #define IMPL_sha3_384_NAME()    "sha3-384"
784  #define IMPL_sha384_NAME()      "sha-384"
785  #define IMPL_rmd320_NAME()      "ripemd-320"
786  #define IMPL_sha512_256_NAME()  "sha-512/256"
787  #define IMPL_sha3_256_NAME()    "sha3-256"
788  #define IMPL_sha256_NAME()      "sha-256"
789  #define IMPL_rmd256_NAME()      "ripemd-256"
790  #define IMPL_blake2s_256_NAME() "blake2s-256"
791  #define IMPL_blake2b_256_NAME() "blake2b-256"
792  #define IMPL_sha512_224_NAME()  "sha-512/224"
793  #define IMPL_sha3_224_NAME()    "sha3-224"
794  #define IMPL_sha224_NAME()      "sha-224"
795  #define IMPL_blake2s_224_NAME() "blake2s-224"
796  #define IMPL_blake2b_384_NAME() "blake2b-384"
797  #define IMPL_tiger_NAME()       "tiger-192"
798  #define IMPL_sha1_NAME()        "sha-1"
799  #define IMPL_rmd160_NAME()      "ripemd-160"
800  #define IMPL_blake2s_160_NAME() "blake2s-160"
801  #define IMPL_blake2b_160_NAME() "blake2b-160"
802  #define IMPL_rmd128_NAME()      "ripemd-128"
803  #define IMPL_md5_NAME()         "md5"
804  #define IMPL_md4_NAME()         "md4"
805  #define IMPL_md2_NAME()         "md2"
806  #define IMPL_blake2s_128_NAME() "blake2s-128"
807  #define IMPL_shake128_NAME()    "shake128"
808  #define IMPL_shake256_NAME()    "shake256"
809  #define IMPL_DIGEST(T)                                                  \
810    const LSplugin_digester_desc_t ltc_##T##_desc = {                     \
811      NULL, IMPL_##T##_NAME(), &T##_desc, NULL,                           \
812      setup_##T##_data, clean_##T##_data,                                 \
813      NULL, NULL, NULL,                                                   \
814      (int[]){ IMPL_##T##_CMDS(), 0 },                                    \
815      NULL, /* No get_param_data */                                       \
816      NULL, /* No gettable */                                             \
817      NULL, /* No settable */                                             \
818      get_##T##_input_size, get_##T##_size,                               \
819      perform_##T##_once,                                                 \
820      start_##T,                                                          \
821      accumulate_##T##_input,                                             \
822      extract_##T##_output,                                               \
823      finalize_##T,                                                       \
824      stop_##T,                                                           \
825    }
826  
827  IMPL_DIGEST(whirlpool);
828  IMPL_DIGEST(sha3_512);
829  IMPL_DIGEST(sha512);
830  IMPL_DIGEST(blake2b_512);
831  IMPL_DIGEST(sha3_384);
832  IMPL_DIGEST(sha384);
833  IMPL_DIGEST(rmd320);
834  IMPL_DIGEST(sha512_256);
835  IMPL_DIGEST(sha3_256);
836  IMPL_DIGEST(sha256);
837  IMPL_DIGEST(rmd256);
838  IMPL_DIGEST(blake2s_256);
839  IMPL_DIGEST(blake2b_256);
840  IMPL_DIGEST(sha512_224);
841  IMPL_DIGEST(sha3_224);
842  IMPL_DIGEST(sha224);
843  IMPL_DIGEST(blake2s_224);
844  IMPL_DIGEST(blake2b_384);
845  IMPL_DIGEST(tiger);
846  IMPL_DIGEST(sha1);
847  IMPL_DIGEST(rmd160);
848  IMPL_DIGEST(blake2s_160);
849  IMPL_DIGEST(blake2b_160);
850  IMPL_DIGEST(rmd128);
851  IMPL_DIGEST(md5);
852  IMPL_DIGEST(md4);
853  IMPL_DIGEST(md2);
854  IMPL_DIGEST(blake2s_128);
855  IMPL_DIGEST(shake128);
856  IMPL_DIGEST(shake256);