/ ltc-macs.c
ltc-macs.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  /*
 18   * MACs have keys, so we end up with the somewhat curious situation, where
 19   * they are offered both as stand-alone en/decrypt operations and as key
 20   * associated operations.  But, that'll do.
 21   */
 22  
 23  #include <stdlib.h>
 24  #include <string.h>
 25  #include <tomcrypt.h>
 26  #include <lscrypto/key.h>
 27  #include <lscrypto/mac.h>
 28  #include <lsplugin/mkobject.h>
 29  #include <lsplugin/mkoperator.h>
 30  #include <lsplugin/param.h>
 31  
 32  #define T(x) LE_status_is_OK(x)
 33  
 34  /*********************************************************************
 35   *
 36   *  Common MAC key
 37   *
 38   *  libtomcrypt doesn't have any separate key object for MACs.  Instead,
 39   *  there's only a state.  Le'Sec does need a key object, though, and
 40   *  this implementation uses that to simply save away the input key bits.
 41   *
 42   *****/
 43  struct mac_key_st {
 44    /* Cached key bits */
 45    unsigned char *key_bits;
 46    size_t key_bits_len;          /* Measured in bits */
 47  
 48    /* Caches for key data operations */
 49    LSC_key_constructor_t *constructor;
 50    LSC_key_extractor_t *extractor;
 51    /* Caches for associated operations */
 52    LSC_mac_t *mac;
 53  };
 54  
 55  /*
 56   * Start with everything that concerns the key, which includes all
 57   * functions that are strictly for associated operatiion.
 58   */
 59  static LE_STATUS new_key_data(LSC_key_t *key, const void *unused)
 60  {
 61    if (key == NULL)
 62      return LE_STS_ERROR;
 63    struct mac_key_st **k = (struct mac_key_st **)&key->lsc_data;
 64  
 65    if (*k == NULL && (*k = malloc(sizeof(**k))) != NULL)
 66      memset(*k, 0, sizeof(**k));
 67    if (*k == NULL)
 68      return LE_STS_FATAL_ERROR;
 69    return LE_STS_SUCCESS;
 70  }
 71  
 72  static LE_STATUS scrub_key_data(LSC_key_t *key)
 73  {
 74    if (key == NULL || key->lsc_data == NULL)
 75      return LE_STS_SUCCESS;
 76  
 77    struct mac_key_st *k = key->lsc_data;
 78  
 79    free(k->key_bits);
 80    /* DO NOTE that we aren't scrubbing the cached associated operations */
 81    return LE_STS_SUCCESS;
 82  }
 83  
 84  static LE_STATUS clean_key_data(LSC_key_t *key)
 85  {
 86    LE_STATUS sts;
 87  
 88    if (key == NULL || key->lsc_data == NULL)
 89      return LE_STS_SUCCESS;
 90    if (T(sts = scrub_key_data(key))) {
 91      struct mac_key_st *k = key->lsc_data;
 92      /*
 93       * The constructor, encryptor and decryptor are cached, so they don't
 94       * provide a destroy function in the operation object, which means
 95       * that the LSC_free_key_{operation}() calls end up doing nothing.
 96       * Therefore, we must destroy them now, using their destroy functions
 97       * (which do exist) directly.
 98       */
 99      LSplugin_destroy_key_constructor(k->constructor);
100      LSplugin_destroy_mac(k->mac);
101      free(k);
102      key->lsc_data = NULL;
103    }
104    return sts;
105  }
106  
107  static LE_STATUS get_key_size(LSC_key_t *key, size_t *keysize)
108  {
109    struct mac_key_st *k = key->lsc_data;
110  
111    if (k->key_bits == NULL)
112      return LE_STS_ERROR;
113    *keysize = k->key_bits_len;
114    return LE_STS_SUCCESS;
115  }
116  
117  static LE_STATUS set_key_constructor(LSC_key_t *key,
118                                       LSC_key_constructor_t *con)
119  {
120    struct mac_key_st *k = key->lsc_data;
121  
122    k->constructor = con;
123    return LE_STS_SUCCESS;
124  }
125  
126  static LE_STATUS set_key_mac(LSC_key_t *key, LSC_mac_t *mac)
127  {
128    struct mac_key_st *k = key->lsc_data;
129  
130    k->mac = mac;
131    return LE_STS_SUCCESS;
132  }
133  
134  /* Key constructor operation with support functions */
135  
136  struct mac_key_constructor_st {
137    LSC_key_t *key;
138  
139    /* Operational parameters */
140  
141    /* Key bits */
142    unsigned char *key_bits;
143    size_t key_bits_len;          /* Measured in bits */
144  
145    /* True when they've been cached in the key itself */
146    _Bool key_bits_cached;
147  };
148  
149  static LE_STATUS scrub_key_constructor_data(LSC_key_constructor_t *op)
150  {
151    if (op == NULL || op->lsc_data == NULL)
152      return LE_STS_SUCCESS;
153  
154    struct mac_key_constructor_st *c = op->lsc_data;
155  
156    memset(c, 0, sizeof(*c));
157    return LE_STS_SUCCESS;
158  }
159  
160  static LE_STATUS new_key_constructor_data(LSC_key_constructor_t *op)
161  {
162    LE_STATUS sts;
163  
164    if (op == NULL)
165      return LE_STS_ERROR;
166  
167    struct mac_key_constructor_st **c
168      = (struct mac_key_constructor_st **)&op->lsc_data;
169  
170      if (*c == NULL && (*c = malloc(sizeof(**c))) != NULL)
171        memset(*c, 0, sizeof(**c));
172    if (*c == NULL)
173      return LE_STS_FATAL_ERROR;
174    return LE_STS_SUCCESS;
175  }
176  
177  static LE_STATUS clean_key_constructor_data(LSC_key_constructor_t *op)
178  {
179    LE_STATUS sts;
180  
181    if (op == NULL || op->lsc_data == NULL)
182      return LE_STS_SUCCESS;
183    if (T(sts = scrub_key_constructor_data(op))) {
184      free(op->lsc_data);
185      op->lsc_data = NULL;
186    }
187    return sts;
188  }
189  
190  static LE_STATUS set_constructor_key(LSC_key_constructor_t *op,
191                                          LSC_key_t *key)
192  {
193    LE_STATUS sts;
194  
195    if (LE_status_is_OK(sts = new_key_constructor_data(op))) {
196      struct mac_key_constructor_st *c = op->lsc_data;
197  
198      c->key = key;
199    }
200    return sts;
201  }
202  
203  static LE_STATUS get_constructor_key(LSC_key_constructor_t *op,
204                                          LSC_key_t **key)
205  {
206    struct mac_key_constructor_st *c = op->lsc_data;
207  
208    *key = c->key;
209    return LE_STS_SUCCESS;
210  }
211  
212  static LE_STATUS construct_key_data(LSC_key_constructor_t *op)
213  {
214    LE_STATUS sts;
215    struct mac_key_constructor_st *c = op->lsc_data;
216    LSC_key_t *key = c != NULL ? c->key : NULL;
217    struct mac_key_st *k = (key != NULL) ? key->lsc_data : NULL;
218  
219    if (c->key_bits_cached)
220      return LE_STS_SUCCESS;
221    if (T(sts = scrub_key_data(key))) {
222      /* Cache the key bits in the key itself too, to support extraction */
223      k->key_bits = c->key_bits;
224      k->key_bits_len = c->key_bits_len;
225      c->key_bits_cached = true;
226    }
227    return sts;
228  }
229  
230  /*********************************************************************
231   *
232   *  Poly1305
233   *
234   *****/
235  
236  static LSplugin_param_functions_t poly1305_key_bits_fns = {
237    offsetof(struct mac_key_constructor_st, key_bits),
238    offsetof(struct mac_key_constructor_st, key_bits_len),
239    0, false,
240    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
241  };
242  #define POLY1305_I_key_bits             1
243  #define POLY1305_P_key_bits                                             \
244    { "key", POLY1305_I_key_bits,                                         \
245        { LSC_DT_bit_string, { { 256,256, 0 }, },                         \
246            .d_auxilliary = { 0 }, },                                     \
247        .p_private = &poly1305_key_bits_fns }
248  static const LSC_param_desc_t gettable_poly1305_constructor_params[] = {
249    POLY1305_P_key_bits,
250    { NULL, }
251  };
252  static const LSC_param_desc_t settable_poly1305_constructor_params[] = {
253    POLY1305_P_key_bits,
254    { NULL, }
255  };
256  
257  static LE_STATUS
258  get_poly1305_construction_param_data(LSC_key_constructor_t *op, void **data)
259  {
260    *data = op->lsc_data;
261    return LE_STS_SUCCESS;
262  }
263  
264  static LE_STATUS
265  get_gettable_poly1305_construction_param_desc(LSC_key_constructor_t *op,
266                                                const LSC_param_desc_t **param_desc)
267  {
268    assert(op != NULL);
269    assert(param_desc != NULL);
270    *param_desc = gettable_poly1305_constructor_params;
271    return LE_STS_SUCCESS;
272  }
273  
274  static LE_STATUS
275  get_settable_poly1305_construction_param_desc(LSC_key_constructor_t *op,
276                                                const LSC_param_desc_t **param_desc)
277  {
278    assert(op != NULL);
279    assert(param_desc != NULL);
280    *param_desc = settable_poly1305_constructor_params;
281    return LE_STS_SUCCESS;
282  }
283  
284  /* The MAC implementation itself */
285  
286  struct mac_state_poly1305_st {
287    /*
288     * Pointer to the associated key, done this way to allow late
289     * construction of the key (i.e. that LSC_construct_key() can
290     * be called after LSC_set_encryptor_key()).
291     * Using the public type allows working with keys from other
292     * plugins (future extension).
293     */
294    LSC_key_t *key;
295  
296    poly1305_state libtomcrypt_data;
297  };
298  
299  static LE_STATUS setup_poly1305_data(LSC_mac_t *mac)
300  {
301    struct mac_state_poly1305_st **state
302      = (struct mac_state_poly1305_st **)&mac->lsc_data;
303    if (*state == NULL) {
304      *state = malloc(sizeof(**state));
305      if (*state == NULL)
306        return LE_STS_FATAL_ERROR;
307      memset(*state, 0, sizeof(**state));
308    }
309    return LE_STS_SUCCESS;
310  }
311  
312  static LE_STATUS clean_poly1305_data(LSC_mac_t *mac)
313  {
314    struct mac_state_poly1305_st **state
315      = (struct mac_state_poly1305_st **)&mac->lsc_data;
316    if (*state != NULL) {
317      free(*state);
318      *state = NULL;
319    }
320    return LE_STS_SUCCESS;
321  }
322  
323  static LE_STATUS set_poly1305_key(LSC_mac_t *mac, LSC_key_t *key)
324  {
325    struct mac_state_poly1305_st *state = mac->lsc_data;
326    state->key = key;
327    return LE_STS_SUCCESS;
328  }
329  
330  #define get_poly1305_param_data                 NULL
331  #define get_gettable_poly1305_param_desc        NULL
332  #define get_settable_poly1305_param_desc        NULL
333  
334  static LE_STATUS get_poly1305_key(LSC_mac_t *mac, LSC_key_t **key)
335  {
336    struct mac_state_poly1305_st *state = mac->lsc_data;
337    *key = state->key;
338    return LE_STS_SUCCESS;
339  }
340  
341  static LE_STATUS get_poly1305_output_size(LSC_mac_t *mac, size_t *size)
342  {
343    *size = 16;
344    return LE_STS_SUCCESS;
345  }
346  
347  static LE_STATUS start_poly1305(LSC_mac_t *mac)
348  {
349    struct mac_state_poly1305_st *state = mac->lsc_data;
350    if (state == NULL)
351      return LE_STS_ERROR;
352    if (state->key == NULL)
353      return LE_STS_ERROR;
354    struct mac_key_st *k = state->key->lsc_data;
355    if (k == NULL)
356      return LE_STS_ERROR;
357    int err;
358    err = poly1305_init(&state->libtomcrypt_data,
359                        k->key_bits, k->key_bits_len / 8);
360    if (err != CRYPT_OK)
361      return LE_STS_ERROR;
362    return LE_STS_SUCCESS;
363  }
364  static LE_STATUS accumulate_poly1305_input(LSC_mac_t *mac,
365                                             const unsigned char *in,
366                                             size_t inlen)
367  {
368    struct mac_state_poly1305_st *state = mac->lsc_data;
369    if (state == NULL)
370      return LE_STS_ERROR;
371    if (in == NULL)
372      return LE_STS_ERROR;
373  
374    int err;
375    err = poly1305_process(&state->libtomcrypt_data, in, inlen);
376    if (err != CRYPT_OK)
377      return LE_STS_ERROR;
378    return LE_STS_SUCCESS;
379  }
380  
381  static LE_STATUS finalize_poly1305(LSC_mac_t *mac,
382                                     unsigned char *out, size_t outsize,
383                                     size_t *outlen)
384  {
385    struct mac_state_poly1305_st *state = mac->lsc_data;
386    if (outsize < 16)
387      return LE_STS_ERROR;
388    if (outlen != NULL) {
389      *outlen = 16;
390      if (out == NULL)
391        return LE_STS_SUCCESS;
392    }
393    unsigned long len = (unsigned long)outsize;
394    int err;
395    err = poly1305_done(&state->libtomcrypt_data, out, &len);
396    if (err != CRYPT_OK)
397      return LE_STS_ERROR;
398    return LE_STS_SUCCESS;
399  }
400  
401  static LE_STATUS stop_poly1305(LSC_mac_t *mac)
402  {
403    struct mac_state_poly1305_st *state = mac->lsc_data;
404    if (state == NULL)
405      return LE_STS_ERROR;
406    return LE_STS_SUCCESS;
407  }
408  
409  /*********************************************************************
410   *
411   *  Blake2b
412   *
413   *****/
414  
415  static LSplugin_param_functions_t blake2b_key_bits_fns = {
416    offsetof(struct mac_key_constructor_st, key_bits),
417    offsetof(struct mac_key_constructor_st, key_bits_len),
418    0, false,
419    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
420  };
421  #define BLAKE2B_I_key_bits              1
422  #define BLAKE2B_P_key_bits                                              \
423    { "key", BLAKE2B_I_key_bits,                                          \
424        { LSC_DT_bit_string, { { 8, 512, 8 }, },                          \
425            .d_auxilliary = { 0 }, },                                     \
426        .p_private = &blake2b_key_bits_fns }
427  static const LSC_param_desc_t gettable_blake2b_constructor_params[] = {
428    BLAKE2B_P_key_bits,
429    { NULL, }
430  };
431  static const LSC_param_desc_t settable_blake2b_constructor_params[] = {
432    BLAKE2B_P_key_bits,
433    { NULL, }
434  };
435  
436  static LE_STATUS
437  get_blake2b_construction_param_data(LSC_key_constructor_t *op, void **data)
438  {
439    *data = op->lsc_data;
440    return LE_STS_SUCCESS;
441  }
442  
443  static LE_STATUS
444  get_gettable_blake2b_construction_param_desc(LSC_key_constructor_t *op,
445                                               const LSC_param_desc_t **param_desc)
446  {
447    assert(op != NULL);
448    assert(param_desc != NULL);
449    *param_desc = gettable_blake2b_constructor_params;
450    return LE_STS_SUCCESS;
451  }
452  
453  static LE_STATUS
454  get_settable_blake2b_construction_param_desc(LSC_key_constructor_t *op,
455                                               const LSC_param_desc_t **param_desc)
456  {
457    assert(op != NULL);
458    assert(param_desc != NULL);
459    *param_desc = settable_blake2b_constructor_params;
460    return LE_STS_SUCCESS;
461  }
462  
463  /* The MAC implementation itself */
464  
465  struct mac_state_blake2b_st {
466    /*
467     * Pointer to the associated key, done this way to allow late
468     * construction of the key (i.e. that LSC_construct_key() can
469     * be called after LSC_set_encryptor_key()).
470     * Using the public type allows working with keys from other
471     * plugins (future extension).
472     */
473    LSC_key_t *key;
474  
475    size_t outlen;
476  
477    blake2bmac_state libtomcrypt_data;
478  };
479  
480  static LE_STATUS setup_blake2b_data(LSC_mac_t *mac)
481  {
482    struct mac_state_blake2b_st **state
483      = (struct mac_state_blake2b_st **)&mac->lsc_data;
484    if (*state == NULL) {
485      *state = malloc(sizeof(**state));
486      if (*state == NULL)
487        return LE_STS_FATAL_ERROR;
488      memset(*state, 0, sizeof(**state));
489    }
490    return LE_STS_SUCCESS;
491  }
492  
493  static LE_STATUS clean_blake2b_data(LSC_mac_t *mac)
494  {
495    struct mac_state_blake2b_st **state
496      = (struct mac_state_blake2b_st **)&mac->lsc_data;
497    if (*state != NULL) {
498      free(*state);
499      *state = NULL;
500    }
501    return LE_STS_SUCCESS;
502  }
503  
504  static LE_STATUS set_blake2b_key(LSC_mac_t *mac, LSC_key_t *key)
505  {
506    struct mac_state_blake2b_st *state = mac->lsc_data;
507    state->key = key;
508    return LE_STS_SUCCESS;
509  }
510  
511  static LE_STATUS get_blake2b_key(LSC_mac_t *mac, LSC_key_t **key)
512  {
513    struct mac_state_blake2b_st *state = mac->lsc_data;
514    *key = state->key;
515    return LE_STS_SUCCESS;
516  }
517  
518  static LE_STATUS get_blake2b_output_size(LSC_mac_t *mac, size_t *size)
519  {
520    struct mac_state_blake2b_st *state = mac->lsc_data;
521    if (state == NULL)
522      *size = 64;
523    else
524      *size = state->outlen;
525    return LE_STS_SUCCESS;
526  }
527  
528  static LSplugin_param_functions_t blake2b_outlen_fns = {
529    offsetof(struct mac_state_blake2b_st, outlen), 0, 0, false,
530    LSplugin_set_size_t_param, LSplugin_get_size_t_param
531  };
532  #define BLAKE2B_I_outlen                2
533  #define BLAKE2B_P_outlen                                        \
534    { "outlen", BLAKE2B_I_outlen,                                 \
535        { LSC_DT_integer,                                         \
536            { { sizeof(size_t), sizeof(size_t) }, }, },           \
537        .p_private = &blake2b_outlen_fns }
538  static const LSC_param_desc_t gettable_blake2b_params[] = {
539    BLAKE2B_P_outlen,
540    { NULL, }
541  };
542  static const LSC_param_desc_t settable_blake2b_params[] = {
543    BLAKE2B_P_outlen,
544    { NULL, }
545  };
546  
547  static LE_STATUS
548  get_blake2b_param_data(LSC_mac_t *op, void **data)
549  {
550    *data = op->lsc_data;
551    return LE_STS_SUCCESS;
552  }
553  
554  static LE_STATUS
555  get_gettable_blake2b_param_desc(LSC_mac_t *mac,
556                                  const LSC_param_desc_t **param_desc)
557  {
558    *param_desc = gettable_blake2b_params;
559    return LE_STS_SUCCESS;
560  }
561  
562  static LE_STATUS
563  get_settable_blake2b_param_desc(LSC_mac_t *mac,
564                                  const LSC_param_desc_t **param_desc)
565  {
566    *param_desc = settable_blake2b_params;
567    return LE_STS_SUCCESS;
568  }
569  
570  static LE_STATUS start_blake2b(LSC_mac_t *mac)
571  {
572    struct mac_state_blake2b_st *state = mac->lsc_data;
573    if (state == NULL)
574      return LE_STS_ERROR;
575    if (state->key == NULL)
576      return LE_STS_ERROR;
577    struct mac_key_st *k = state->key->lsc_data;
578    if (k == NULL)
579      return LE_STS_ERROR;
580    int err;
581    err = blake2b_init(&state->libtomcrypt_data, (unsigned long)state->outlen,
582                       k->key_bits, k->key_bits_len / 8);
583    if (err != CRYPT_OK)
584      return LE_STS_ERROR;
585    return LE_STS_SUCCESS;
586  }
587  static LE_STATUS accumulate_blake2b_input(LSC_mac_t *mac,
588                                            const unsigned char *in,
589                                            size_t inlen)
590  {
591    struct mac_state_blake2b_st *state = mac->lsc_data;
592    if (state == NULL)
593      return LE_STS_ERROR;
594    if (in == NULL)
595      return LE_STS_ERROR;
596  
597    int err;
598    err = blake2b_process(&state->libtomcrypt_data, in, inlen);
599    if (err != CRYPT_OK)
600      return LE_STS_ERROR;
601    return LE_STS_SUCCESS;
602  }
603  
604  static LE_STATUS finalize_blake2b(LSC_mac_t *mac,
605                                    unsigned char *out, size_t outsize,
606                                    size_t *outlen)
607  {
608    struct mac_state_blake2b_st *state = mac->lsc_data;
609    if (outsize < state->outlen)
610      return LE_STS_ERROR;
611    if (outlen != NULL) {
612      *outlen = state->outlen;
613      if (out == NULL)
614        return LE_STS_SUCCESS;
615    }
616    unsigned long len = (unsigned long)outsize;
617    int err;
618    err = blake2bmac_done(&state->libtomcrypt_data, out, &len);
619    if (err != CRYPT_OK)
620      return LE_STS_ERROR;
621    return LE_STS_SUCCESS;
622  }
623  
624  static LE_STATUS stop_blake2b(LSC_mac_t *mac)
625  {
626    struct mac_state_blake2b_st *state = mac->lsc_data;
627    if (state == NULL)
628      return LE_STS_ERROR;
629    return LE_STS_SUCCESS;
630  }
631  
632  /*********************************************************************
633   *
634   *  Blake2s
635   *
636   *****/
637  
638  static LSplugin_param_functions_t blake2s_key_bits_fns = {
639    offsetof(struct mac_key_constructor_st, key_bits),
640    offsetof(struct mac_key_constructor_st, key_bits_len),
641    0, false,
642    LSplugin_set_bitstring_param, LSplugin_get_bitstring_param
643  };
644  #define BLAKE2S_I_key_bits              1
645  #define BLAKE2S_P_key_bits                                              \
646    { "key", BLAKE2S_I_key_bits,                                          \
647        { LSC_DT_bit_string, { { 8, 512, 8 }, },                          \
648            .d_auxilliary = { 0 }, },                                     \
649        .p_private = &blake2s_key_bits_fns }
650  static const LSC_param_desc_t gettable_blake2s_constructor_params[] = {
651    BLAKE2S_P_key_bits,
652    { NULL, }
653  };
654  static const LSC_param_desc_t settable_blake2s_constructor_params[] = {
655    BLAKE2S_P_key_bits,
656    { NULL, }
657  };
658  
659  static LE_STATUS
660  get_blake2s_construction_param_data(LSC_key_constructor_t *op, void **data)
661  {
662    *data = op->lsc_data;
663    return LE_STS_SUCCESS;
664  }
665  
666  static LE_STATUS
667  get_gettable_blake2s_construction_param_desc(LSC_key_constructor_t *op,
668                                               const LSC_param_desc_t **param_desc)
669  {
670    assert(op != NULL);
671    assert(param_desc != NULL);
672    *param_desc = gettable_blake2s_constructor_params;
673    return LE_STS_SUCCESS;
674  }
675  
676  static LE_STATUS
677  get_settable_blake2s_construction_param_desc(LSC_key_constructor_t *op,
678                                               const LSC_param_desc_t **param_desc)
679  {
680    assert(op != NULL);
681    assert(param_desc != NULL);
682    *param_desc = settable_blake2s_constructor_params;
683    return LE_STS_SUCCESS;
684  }
685  
686  /* The MAC implementation itself */
687  
688  struct mac_state_blake2s_st {
689    /*
690     * Pointer to the associated key, done this way to allow late
691     * construction of the key (i.e. that LSC_construct_key() can
692     * be called after LSC_set_encryptor_key()).
693     * Using the public type allows working with keys from other
694     * plugins (future extension).
695     */
696    LSC_key_t *key;
697  
698    size_t outlen;
699  
700    blake2smac_state libtomcrypt_data;
701  };
702  
703  static LE_STATUS setup_blake2s_data(LSC_mac_t *mac)
704  {
705    struct mac_state_blake2s_st **state
706      = (struct mac_state_blake2s_st **)&mac->lsc_data;
707    if (*state == NULL) {
708      *state = malloc(sizeof(**state));
709      if (*state == NULL)
710        return LE_STS_FATAL_ERROR;
711      memset(*state, 0, sizeof(**state));
712    }
713    return LE_STS_SUCCESS;
714  }
715  
716  static LE_STATUS clean_blake2s_data(LSC_mac_t *mac)
717  {
718    struct mac_state_blake2s_st **state
719      = (struct mac_state_blake2s_st **)&mac->lsc_data;
720    if (*state != NULL) {
721      free(*state);
722      *state = NULL;
723    }
724    return LE_STS_SUCCESS;
725  }
726  
727  static LE_STATUS set_blake2s_key(LSC_mac_t *mac, LSC_key_t *key)
728  {
729    struct mac_state_blake2s_st *state = mac->lsc_data;
730    state->key = key;
731    return LE_STS_SUCCESS;
732  }
733  
734  static LE_STATUS get_blake2s_key(LSC_mac_t *mac, LSC_key_t **key)
735  {
736    struct mac_state_blake2s_st *state = mac->lsc_data;
737    *key = state->key;
738    return LE_STS_SUCCESS;
739  }
740  
741  static LE_STATUS get_blake2s_output_size(LSC_mac_t *mac, size_t *size)
742  {
743    struct mac_state_blake2s_st *state = mac->lsc_data;
744    if (state == NULL)
745      *size = 64;
746    else
747      *size = state->outlen;
748    return LE_STS_SUCCESS;
749  }
750  
751  static LSplugin_param_functions_t blake2s_outlen_fns = {
752    offsetof(struct mac_state_blake2s_st, outlen), 0, 0, false,
753    LSplugin_set_size_t_param, LSplugin_get_size_t_param
754  };
755  #define BLAKE2S_I_outlen                2
756  #define BLAKE2S_P_outlen                                        \
757    { "outlen", BLAKE2S_I_outlen,                                 \
758        { LSC_DT_integer,                                         \
759            { { sizeof(size_t), sizeof(size_t) }, }, },           \
760        .p_private = &blake2s_outlen_fns }
761  static const LSC_param_desc_t gettable_blake2s_params[] = {
762    BLAKE2S_P_outlen,
763    { NULL, }
764  };
765  static const LSC_param_desc_t settable_blake2s_params[] = {
766    BLAKE2S_P_outlen,
767    { NULL, }
768  };
769  
770  static LE_STATUS
771  get_blake2s_param_data(LSC_mac_t *op, void **data)
772  {
773    *data = op->lsc_data;
774    return LE_STS_SUCCESS;
775  }
776  
777  static LE_STATUS
778  get_gettable_blake2s_param_desc(LSC_mac_t *mac,
779                                  const LSC_param_desc_t **param_desc)
780  {
781    *param_desc = gettable_blake2s_params;
782    return LE_STS_SUCCESS;
783  }
784  
785  static LE_STATUS
786  get_settable_blake2s_param_desc(LSC_mac_t *mac,
787                                  const LSC_param_desc_t **param_desc)
788  {
789    *param_desc = settable_blake2s_params;
790    return LE_STS_SUCCESS;
791  }
792  
793  static LE_STATUS start_blake2s(LSC_mac_t *mac)
794  {
795    struct mac_state_blake2s_st *state = mac->lsc_data;
796    if (state == NULL)
797      return LE_STS_ERROR;
798    if (state->key == NULL)
799      return LE_STS_ERROR;
800    struct mac_key_st *k = state->key->lsc_data;
801    if (k == NULL)
802      return LE_STS_ERROR;
803    int err;
804    err = blake2s_init(&state->libtomcrypt_data, (unsigned long)state->outlen,
805                       k->key_bits, k->key_bits_len / 8);
806    if (err != CRYPT_OK)
807      return LE_STS_ERROR;
808    return LE_STS_SUCCESS;
809  }
810  static LE_STATUS accumulate_blake2s_input(LSC_mac_t *mac,
811                                            const unsigned char *in,
812                                            size_t inlen)
813  {
814    struct mac_state_blake2s_st *state = mac->lsc_data;
815    if (state == NULL)
816      return LE_STS_ERROR;
817    if (in == NULL)
818      return LE_STS_ERROR;
819  
820    int err;
821    err = blake2s_process(&state->libtomcrypt_data, in, inlen);
822    if (err != CRYPT_OK)
823      return LE_STS_ERROR;
824    return LE_STS_SUCCESS;
825  }
826  
827  static LE_STATUS finalize_blake2s(LSC_mac_t *mac,
828                                    unsigned char *out, size_t outsize,
829                                    size_t *outlen)
830  {
831    struct mac_state_blake2s_st *state = mac->lsc_data;
832    if (outsize < state->outlen)
833      return LE_STS_ERROR;
834    if (outlen != NULL) {
835      *outlen = state->outlen;
836      if (out == NULL)
837        return LE_STS_SUCCESS;
838    }
839    unsigned long len = (unsigned long)outsize;
840    int err;
841    err = blake2smac_done(&state->libtomcrypt_data, out, &len);
842    if (err != CRYPT_OK)
843      return LE_STS_ERROR;
844    return LE_STS_SUCCESS;
845  }
846  
847  static LE_STATUS stop_blake2s(LSC_mac_t *mac)
848  {
849    struct mac_state_blake2s_st *state = mac->lsc_data;
850    if (state == NULL)
851      return LE_STS_ERROR;
852    return LE_STS_SUCCESS;
853  }
854  
855  /*********************************************************************
856   *
857   *  Common operator functions
858   *
859   *****/
860  
861  /*********************************************************************
862   *
863   *  Implementation tables
864   *
865   *****/
866  
867  #define IMPL_poly1305_NAME()              "poly1305"
868  #define IMPL_blake2b_NAME()               "blake2b"
869  #define IMPL_blake2s_NAME()               "blake2s"
870  #define IMPL_MAC_OP(N)                                                  \
871    const LSplugin_mac_desc_t ltc_##N##_mac_desc = {                      \
872      NULL, IMPL_##N##_NAME(), NULL, IMPL_##N##_NAME(),                   \
873      setup_##N##_data, clean_##N##_data,                                 \
874      NULL, set_##N##_key, get_##N##_key,                                 \
875      (int[]){ LSC_MAC_TYPE_BASE_COMMANDS(),                              \
876               LSC_MAC_SIZE_COMMANDS(),                                   \
877               LSC_NR_start_mac,                                          \
878               LSC_NR_accumulate_mac_input,                               \
879               LSC_NR_finalize_mac,                                       \
880               LSC_NR_stop_mac, 0 },                                      \
881      get_##N##_param_data,                                               \
882      get_gettable_##N##_param_desc,                                      \
883      get_settable_##N##_param_desc,                                      \
884      NULL,                       /* No get_##N##_input_size */           \
885      get_##N##_output_size,                                              \
886      NULL, /* No perform once */                                         \
887      start_##N,                                                          \
888      accumulate_##N##_input,                                             \
889      finalize_##N,                                                       \
890      stop_##N,                                                           \
891    };
892  #define IMPL_KEY_CONSTRUCTOR_OP(N)                                      \
893    static const LSplugin_key_constructor_desc_t                          \
894    ltc_##N##_key_constructor_desc = {                                    \
895      NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \
896      new_key_constructor_data, clean_key_constructor_data,               \
897      set_key_constructor, set_constructor_key, get_constructor_key,      \
898      (int[]){ LSC_KEY_TYPE_CONSTRUCTOR_COMMANDS(),                       \
899               LSC_NR_get_settable_key_construction_param_desc,           \
900               LSC_NR_set_key_construction_param,                         \
901               LSC_NR_get_gettable_key_construction_param_desc,           \
902               LSC_NR_get_key_construction_param,                         \
903               LSC_NR_construct_key, 0 },                                 \
904      get_##N##_construction_param_data,                                  \
905      get_gettable_##N##_construction_param_desc, /* gettable */          \
906      get_settable_##N##_construction_param_desc, /* settable */          \
907      construct_key_data                                                  \
908    }
909  #define IMPL_KEY_MAC_OP(N)                                              \
910    static const LSplugin_mac_desc_t ltc_##N##_key_mac_desc = {           \
911      NULL, NULL, NULL, NULL, /* lsp_docstring, lsp_id, lsp_priv_desc, lsp_key_id */ \
912      NULL, NULL,                                                         \
913      set_key_mac, set_##N##_key, get_##N##_key,                          \
914      (int[]){ LSC_MAC_TYPE_BASE_COMMANDS(),                              \
915               LSC_MAC_SIZE_COMMANDS(),                                   \
916               LSC_NR_start_mac,                                          \
917               LSC_NR_accumulate_mac_input,                               \
918               LSC_NR_finalize_mac,                                       \
919               LSC_NR_stop_mac, 0 },                                      \
920      NULL, /* No get_##N##_param_data */                                 \
921      NULL, /* No get_gettable_##N##_param_desc */                        \
922      NULL, /* No get_settable_##N##_param_desc */                        \
923      NULL, /* No get_##N##_input_size */                                 \
924      get_##N##_output_size,                                              \
925      NULL, /* No perform once */                                         \
926      start_##N,                                                          \
927      accumulate_##N##_input,                                             \
928      finalize_##N,                                                       \
929      stop_##N,                                                           \
930    }
931  #define IMPL_MAC_KEY(N)                                                 \
932    IMPL_KEY_CONSTRUCTOR_OP(N);                                           \
933    IMPL_KEY_MAC_OP(N);                                                   \
934    const LSplugin_key_desc_t ltc_##N##_desc = {                          \
935      NULL, IMPL_##N##_NAME(), NULL,                                      \
936      new_key_data, clean_key_data,                                       \
937      (int[]){ LSC_KEY_TYPE_BASE_COMMANDS(),                              \
938               LSC_NR_get_key_size,                                       \
939               LSC_NR_get_key_constructor,                                \
940               LSC_NR_get_associated_mac, 0 },                      \
941      get_key_size,                                                       \
942      NULL,                    /* No key generator */                     \
943      &ltc_##N##_key_constructor_desc,                                    \
944      NULL,                    /* No key extractor */                     \
945      NULL,                    /* No encryptor */                         \
946      NULL,                    /* No decryptor */                         \
947      NULL,                    /* No signer */                            \
948      NULL,                    /* No verifier */                          \
949      NULL,                    /* No derivator */                         \
950      &ltc_##N##_key_mac_desc,                                            \
951    }
952  #define IMPL_MAC(N)                                                     \
953    IMPL_MAC_OP(N);                                                       \
954    IMPL_MAC_KEY(N)
955  
956  IMPL_MAC(poly1305);
957  IMPL_MAC(blake2b);
958  IMPL_MAC(blake2s);