Commit | Line | Data |
---|---|---|
37941236 | 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) { | |
f43df819 | 112 | a_warn("CHAL", "invalid-challenge", A_END); |
37941236 | 113 | goto fail; |
114 | } | |
115 | IF_TRACING(T_CHAL, trace_block(T_CRYPTO, "chal: check challenge", p, sz); ) | |
116 | if (!mac) { | |
f43df819 | 117 | a_warn("CHAL", "impossible-challenge", A_END); |
37941236 | 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) { | |
f43df819 | 125 | a_warn("CHAL", "incorrect-tag", A_END); |
37941236 | 126 | goto fail; |
127 | } | |
128 | seq = LOAD32(p); | |
f43df819 MW |
129 | if (seq_check(&iseq, LOAD32(p), "CHAL")) |
130 | goto fail; | |
37941236 | 131 | T( trace(T_CHAL, "chal: checked challenge %lu", (unsigned long)seq); ) |
132 | return (0); | |
133 | ||
134 | fail: | |
135 | buf_break(b); | |
136 | return (-1); | |
137 | } | |
138 | ||
139 | /*----- That's all, folks -------------------------------------------------*/ |