1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file pmac_done.c
7 PMAC implementation, terminate a session, by Tom St Denis
8 */
9
10 #ifdef LTC_PMAC
11
pmac_done(pmac_state * pmac,unsigned char * out,unsigned long * outlen)12 int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen)
13 {
14 int err, x;
15
16 LTC_ARGCHK(pmac != NULL);
17 LTC_ARGCHK(out != NULL);
18 if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) {
19 return err;
20 }
21
22 if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) ||
23 (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) {
24 return CRYPT_INVALID_ARG;
25 }
26
27
28 /* handle padding. If multiple xor in L/x */
29
30 if (pmac->buflen == pmac->block_len) {
31 /* xor Lr against the checksum */
32 for (x = 0; x < pmac->block_len; x++) {
33 pmac->checksum[x] ^= pmac->block[x] ^ pmac->Lr[x];
34 }
35 } else {
36 /* otherwise xor message bytes then the 0x80 byte */
37 for (x = 0; x < pmac->buflen; x++) {
38 pmac->checksum[x] ^= pmac->block[x];
39 }
40 pmac->checksum[x] ^= 0x80;
41 }
42
43 /* encrypt it */
44 if ((err = cipher_descriptor[pmac->cipher_idx]->ecb_encrypt(pmac->checksum, pmac->checksum, &pmac->key)) != CRYPT_OK) {
45 return err;
46 }
47 cipher_descriptor[pmac->cipher_idx]->done(&pmac->key);
48
49 /* store it */
50 for (x = 0; x < pmac->block_len && x < (int)*outlen; x++) {
51 out[x] = pmac->checksum[x];
52 }
53 *outlen = x;
54
55 #ifdef LTC_CLEAN_STACK
56 zeromem(pmac, sizeof(*pmac));
57 #endif
58 return CRYPT_OK;
59 }
60
61 #endif
62
63