chiark / gitweb /
math/gfx-sqr.c: Use bithacking rather than a table for squaring.
[catacomb] / symm / gaead.c
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
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
46 int 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
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
76 int 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);
92 end:
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
121 int 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);
137 end:
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 -------------------------------------------------*/