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