chiark / gitweb /
Greetings and challenges.
[tripe] / chal.c
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Cryptographic challenges
6  *
7  * (c) 2005 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Trivial IP Encryption (TrIPE).
13  *
14  * TrIPE is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * TrIPE is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with TrIPE; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Header files ------------------------------------------------------*/
30
31 #include "tripe.h"
32
33 /*----- Static variables --------------------------------------------------*/
34
35 static gmac *mac;
36 static uint32 oseq;
37 static seqwin iseq;
38
39 /*----- Main code ---------------------------------------------------------*/
40
41 /* --- @c_genkey@ --- *
42  *
43  * Arguments:   ---
44  *
45  * Returns:     ---
46  *
47  * Use:         Generates a new challenge key.
48  */
49
50 static void c_genkey(void)
51 {
52   if (mac && GM_CLASS(mac) == algs.m && oseq < 0x07ffffff) return;
53   if (mac) GM_DESTROY(mac);
54   assert(algs.mksz < sizeof(buf_t));
55   rand_get(RAND_GLOBAL, buf_t, algs.mksz);
56   mac = GM_KEY(algs.m, buf_t, algs.mksz);
57   oseq = 0;
58   seq_reset(&iseq);
59   IF_TRACING(T_CHAL, {
60     trace(T_CHAL, "chal: generated new challenge key");
61     trace_block(T_CRYPTO, "chal: new key", buf_t, algs.mksz);
62   })
63 }
64
65 /* --- @c_new@ --- *
66  *
67  * Arguments:   @buf *b@ = where to put the challenge
68  *
69  * Returns:     Zero if OK, nonzero on error.
70  *
71  * Use:         Issues a new challenge.
72  */
73
74 int c_new(buf *b)
75 {
76   octet *p;
77   ghash *h;
78
79   c_genkey();
80   p = BCUR(b);
81   if (buf_putu32(b, oseq++)) return (-1);
82   h = GM_INIT(mac);
83   GH_HASH(h, p, BCUR(b) - p);
84   buf_put(b, GH_DONE(h, 0), algs.tagsz);
85   GH_DESTROY(h);
86   if (BBAD(b)) return (-1);
87   IF_TRACING(T_CHAL, {
88     trace(T_CHAL, "chal: issuing challenge %lu", (unsigned long)(oseq - 1));
89     trace_block(T_CRYPTO, "chal: challenge block", p, BCUR(b) - p);
90   })
91   return (0);
92 }
93
94 /* --- @c_check@ --- *
95  *
96  * Arguments:   @buf *b@ = where to find the challenge
97  *
98  * Returns:     Zero if OK, nonzero if it didn't work.
99  *
100  * Use:         Checks a challenge.  On failure, the buffer is broken.
101  */
102
103 int c_check(buf *b)
104 {
105   const octet *p;
106   size_t sz = 4 + algs.tagsz;
107   uint32 seq;
108   ghash *h;
109   int ok;
110
111   if ((p = buf_get(b, sz)) == 0) {
112     a_warn("CHAL invalid-challenge");
113     goto fail;
114   }
115   IF_TRACING(T_CHAL, trace_block(T_CRYPTO, "chal: check challenge", p, sz); )
116   if (!mac) {
117     a_warn("CHAL impossible-challenge");
118     goto fail;
119   }
120   h = GM_INIT(mac);
121   GH_HASH(h, p, 4);
122   ok = (memcmp(GH_DONE(h, 0), p + 4, algs.tagsz) == 0);
123   GH_DESTROY(h);
124   if (!ok) {
125     a_warn("CHAL incorrect-tag");
126     goto fail;
127   }
128   seq = LOAD32(p);
129   switch (seq_check(&iseq, LOAD32(p))) {
130     case SEQ_OK: break;
131     case SEQ_OLD: a_warn("CHAL replay old-sequence"); goto fail;
132     case SEQ_REPLAY: a_warn("CHAL replay duplicated-sequence"); goto fail;
133     default: abort();
134   }
135   T( trace(T_CHAL, "chal: checked challenge %lu", (unsigned long)seq); )
136   return (0);
137
138 fail:
139   buf_break(b);
140   return (-1);
141 }
142
143 /*----- That's all, folks -------------------------------------------------*/