chiark / gitweb /
server/keymgmt.c: Track and find keys by their 32-bit IDs.
[tripe] / server / chal.c
1 /* -*-c-*-
2  *
3  * Cryptographic challenges
4  *
5  * (c) 2005 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Trivial IP Encryption (TrIPE).
11  *
12  * TrIPE is free software: you can redistribute it and/or modify it under
13  * the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your
15  * option) any later version.
16  *
17  * TrIPE is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with TrIPE.  If not, see <https://www.gnu.org/licenses/>.
24  */
25
26 /*----- Header files ------------------------------------------------------*/
27
28 #include "tripe.h"
29
30 /*----- Static variables --------------------------------------------------*/
31
32 static bulkchal *bchal;
33 static uint32 oseq;
34 static seqwin iseq;
35
36 /*----- Challenges --------------------------------------------------------*/
37
38 /* --- @c_genkey@ --- *
39  *
40  * Arguments:   ---
41  *
42  * Returns:     ---
43  *
44  * Use:         Generates a new challenge key.
45  */
46
47 static void c_genkey(void)
48 {
49   bulkalgs *bulk = master->algs.bulk;
50   if (bchal && bchal->ops == bulk->ops && oseq < 0x07ffffff) return;
51   if (bchal) bchal->ops->freechal(bchal);
52   bchal = bulk->ops->genchal(bulk);
53   bchal->ops = bulk->ops;
54   oseq = 0;
55   seq_reset(&iseq);
56 }
57
58 /* --- @c_new@ --- *
59  *
60  * Arguments:   @const void *m@ = pointer to associated message, or null
61  *              @size_t msz@ = length of associated message
62  *              @buf *b@ = where to put the challenge
63  *
64  * Returns:     Zero if OK, nonzero on error.
65  *
66  * Use:         Issues a new challenge.
67  */
68
69 int c_new(const void *m, size_t msz, buf *b)
70 {
71   const octet *p;
72   octet *t;
73   int rc;
74
75   c_genkey();
76   p = BCUR(b);
77   if (buf_putu32(b, oseq) || (t = buf_get(b, bchal->tagsz)) == 0)
78     { rc = -1; goto done; }
79   if (bchal->ops->chaltag(bchal, m, msz, oseq, t)) { rc = -1; goto done; }
80   IF_TRACING(T_CHAL, {
81     trace(T_CHAL, "chal: issuing challenge %lu", (unsigned long)oseq);
82     if (msz) trace_block(T_CRYPTO, "chal: message block", m, msz);
83     trace_block(T_CRYPTO, "chal: challenge block", p, BCUR(b) - p);
84   })
85   rc = 0;
86 done:
87   oseq++;
88   return (rc);
89 }
90
91 /* --- @c_check@ --- *
92  *
93  * Arguments:   @const void *m@ = pointer to associated message, or null
94  *              @size_t msz@ = length of associated message
95  *              @buf *b@ = where to find the challenge
96  *
97  * Returns:     Zero if OK, nonzero if it didn't work.
98  *
99  * Use:         Checks a challenge.  On failure, the buffer is broken.
100  */
101
102 int c_check(const void *m, size_t msz, buf *b)
103 {
104   const octet *p, *t;
105   uint32 seq;
106
107   if (!bchal) {
108     a_warn("CHAL", "impossible-challenge", A_END);
109     goto fail;
110   }
111   p = BCUR(b);
112   if (buf_getu32(b, &seq) || (t = buf_get(b, bchal->tagsz)) == 0) {
113     a_warn("CHAL", "invalid-challenge", A_END);
114     goto fail;
115   }
116   IF_TRACING(T_CHAL, {
117     trace(T_CHAL, "chal: checking challenge, seq = %lu", (unsigned long)seq);
118     if (msz) trace_block(T_CRYPTO, "chal: message block", m, msz);
119     trace_block(T_CRYPTO, "chal: check challenge", p, BCUR(b) - p);
120   })
121   if (bchal->ops->chalvrf(bchal, m, msz, seq, t)) {
122     a_warn("CHAL", "incorrect-tag", A_END);
123     goto fail;
124   }
125   if (seq_check(&iseq, seq, "CHAL")) goto fail;
126   T( trace(T_CHAL, "chal: challenge ok"); )
127   return (0);
128
129 fail:
130   buf_break(b);
131   return (-1);
132 }
133
134 /*----- That's all, folks -------------------------------------------------*/