progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / gaead.c
CommitLineData
96a5a09c
MW
1/* -*-c-*-
2 *
3 * Generic authenticated encryption interface
4 *
5 * (c) 2018 Straylight/Edgeware
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Catacomb.
11 *
12 * Catacomb is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU Library General Public License as published
14 * by the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * Catacomb is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb. If not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * USA.
26 */
27
28/*----- Header files ------------------------------------------------------*/
29
30#include "gaead.h"
31
32/*----- Main code ---------------------------------------------------------*/
33
1491bf9e
MW
34/* --- @gaead_szokcommon@ --- *
35 *
36 * Arguments: @const gcaead *aec@ = pointer to AEAD class
37 * @size_t nsz@, @size_t hsz@, @size_t msz@, @size_t tsz@ =
38 * nonce, header, message, and tag sizes
39 *
40 * Returns: Nonzero if the sizes are acceptable to the AEAD scheme in
41 * combination.
42 *
43 * Use: Generic implementation for sensible AEAD schemes.
44 */
45
46int gaead_szokcommon(const gcaead *aec,
47 size_t nsz, size_t hsz, size_t msz, size_t tsz)
48{
49 if (keysz(nsz, aec->noncesz) != nsz) return (0);
50 if (keysz(tsz, aec->tagsz) != tsz) return (0);
51 if (hsz && (aec->f&AEADF_NOAAD)) return (0);
52 return (1);
53}
54
96a5a09c
MW
55/* --- @gaead_encrypt@ --- *
56 *
57 * Arguments: @const gaead_key *k@ = the AEAD key, already prepared
58 * @const void *n@, @size_t nsz@ = nonce
59 * @const void *h@, @size_t hsz@ = additional `header' data
60 * @const void *m@, @size_t msz@ = message input
61 * @void *c@, @size_t *csz_input@ = ciphertext output
62 * @void *t@, @size_t tsz@ = tag output
63 *
64 * Returns: Zero on success, @-1@ if the output buffer is too small.
65 *
66 * Use: Encrypts and authenticates a message in a single operation.
67 * This just saves a bunch of messing about with the various
68 * @gaead_...@ objects.
69 *
70 * On entry, @*csz_inout@ should be the capacity of the
71 * ciphertext buffer; on exit, it will be updated with the
72 * actual size of ciphertext produced. The function will not
73 * fail if @*csz_inout >= msz + k->c->ohd@.
74 */
75
76int gaead_encrypt(const gaead_key *k, const void *n, size_t nsz,
77 const void *h, size_t hsz,
78 const void *m, size_t msz,
79 void *c, size_t *csz_inout,
80 void *t, size_t tsz)
81{
82 gaead_enc *e = 0;
83 gaead_aad *a = 0;
84 buf b;
85 int rc;
86
87 buf_init(&b, c, *csz_inout);
88 e = GAEAD_ENC(k, n, nsz, hsz, msz, tsz); if (!e) { rc = -1; goto end; }
89 if (hsz) { a = GAEAD_AAD(e); GAEAD_HASH(a, h, hsz); }
90 rc = GAEAD_ENCRYPT(e, m, msz, &b); if (rc) goto end;
91 rc = GAEAD_DONE(e, a, &b, t, tsz);
92end:
93 if (rc >= 0) *csz_inout = BLEN(&b);
94 if (e) GAEAD_DESTROY(e);
95 if (a) GAEAD_DESTROY(a);
96 return (rc);
97}
98
99/* --- @gaead_decrypt@ --- *
100 *
101 * Arguments: @const gaead_key *k@ = the AEAD key, already prepared
102 * @const void *n@, @size_t nsz@ = nonce
103 * @const void *h@, @size_t hsz@ = additional `header' data
104 * @const void *c@, @size_t csz@ = ciphertext input
105 * @void *m@, @size_t *msz_inout@ = message output
106 * @const void *t@, @size_t tsz@ = tag input
107 *
108 * Returns: @+1@ if everything is good; zero for authentication failure,
109 * @-1@ for other problems.
110 *
111 * Use: Decrypts and verifies a message in a single operation.
112 * This just saves a bunch of messing about with the various
113 * @gaead_...@ objects.
114 *
115 * On entry, @*msz_inout@ should be the capacity of the
116 * message buffer; on exit, it will be updated with the
117 * actual size of message produced. The function will not
118 * fail if @*msz_inout >= csz@.
119 */
120
121int gaead_decrypt(const gaead_key *k, const void *n, size_t nsz,
122 const void *h, size_t hsz,
123 const void *c, size_t csz,
124 void *m, size_t *msz_inout,
125 const void *t, size_t tsz)
126{
127 gaead_dec *d = 0;
128 gaead_aad *a = 0;
129 buf b;
130 int rc;
131
132 buf_init(&b, m, *msz_inout);
133 d = GAEAD_DEC(k, n, nsz, hsz, csz, tsz); if (!d) { rc = -1; goto end; }
134 if (hsz) { a = GAEAD_AAD(d); GAEAD_HASH(a, h, hsz); }
135 rc = GAEAD_DECRYPT(d, c, csz, &b); if (rc) goto end;
136 rc = GAEAD_DONE(d, a, &b, t, tsz);
137end:
138 if (rc >= 0) *msz_inout = BLEN(&b);
139 if (d) GAEAD_DESTROY(d);
140 if (a) GAEAD_DESTROY(a);
141 return (rc);
142}
143
144/*----- That's all, folks -------------------------------------------------*/