OpenCoverage

mac.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/mac.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: mac.c,v 1.34 2017/05/08 22:57:38 djm Exp $ */-
2/*-
3 * Copyright (c) 2001 Markus Friedl. All rights reserved.-
4 *-
5 * Redistribution and use in source and binary forms, with or without-
6 * modification, are permitted provided that the following conditions-
7 * are met:-
8 * 1. Redistributions of source code must retain the above copyright-
9 * notice, this list of conditions and the following disclaimer.-
10 * 2. Redistributions in binary form must reproduce the above copyright-
11 * notice, this list of conditions and the following disclaimer in the-
12 * documentation and/or other materials provided with the distribution.-
13 *-
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR-
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES-
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.-
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,-
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT-
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,-
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY-
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT-
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF-
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-
24 */-
25-
26#include "includes.h"-
27-
28#include <sys/types.h>-
29-
30#include <string.h>-
31#include <stdio.h>-
32-
33#include "digest.h"-
34#include "hmac.h"-
35#include "umac.h"-
36#include "mac.h"-
37#include "misc.h"-
38#include "ssherr.h"-
39#include "sshbuf.h"-
40-
41#include "openbsd-compat/openssl-compat.h"-
42-
43#define SSH_DIGEST 1 /* SSH_DIGEST_XXX */-
44#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */-
45#define SSH_UMAC128 3-
46-
47struct macalg {-
48 char *name;-
49 int type;-
50 int alg;-
51 int truncatebits; /* truncate digest if != 0 */-
52 int key_len; /* just for UMAC */-
53 int len; /* just for UMAC */-
54 int etm; /* Encrypt-then-MAC */-
55};-
56-
57static const struct macalg macs[] = {-
58 /* Encrypt-and-MAC (encrypt-and-authenticate) variants */-
59 { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 },-
60 { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 },-
61#ifdef HAVE_EVP_SHA256-
62 { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 },-
63 { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 },-
64#endif-
65 { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },-
66 { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },-
67 { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },-
68 { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },-
69-
70 /* Encrypt-then-MAC variants */-
71 { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 },-
72 { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 },-
73#ifdef HAVE_EVP_SHA256-
74 { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 },-
75 { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 },-
76#endif-
77 { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },-
78 { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },-
79 { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },-
80 { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },-
81-
82 { NULL, 0, 0, 0, 0, 0, 0 }-
83};-
84-
85/* Returns a list of supported MACs separated by the specified char. */-
86char *-
87mac_alg_list(char sep)-
88{-
89 char *ret = NULL, *tmp;-
90 size_t nlen, rlen = 0;-
91 const struct macalg *m;-
92-
93 for (m = macs; m->name != NULL; m++) {
m->name != ((void *)0)Description
TRUEevaluated 32 times by 1 test
Evaluated by:
  • sshd
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
2-32
94 if (ret != NULL)
ret != ((void *)0)Description
TRUEevaluated 30 times by 1 test
Evaluated by:
  • sshd
FALSEevaluated 2 times by 1 test
Evaluated by:
  • sshd
2-30
95 ret[rlen++] = sep;
executed 30 times by 1 test: ret[rlen++] = sep;
Executed by:
  • sshd
30
96 nlen = strlen(m->name);-
97 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
(tmp = realloc...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 32 times by 1 test
Evaluated by:
  • sshd
0-32
98 free(ret);-
99 return NULL;
never executed: return ((void *)0) ;
0
100 }-
101 ret = tmp;-
102 memcpy(ret + rlen, m->name, nlen + 1);-
103 rlen += nlen;-
104 }
executed 32 times by 1 test: end of block
Executed by:
  • sshd
32
105 return ret;
executed 2 times by 1 test: return ret;
Executed by:
  • sshd
2
106}-
107-
108static int-
109mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg)-
110{-
111 mac->type = macalg->type;-
112 if (mac->type == SSH_DIGEST) {
mac->type == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
113 if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
(mac->hmac_ctx...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
114 return SSH_ERR_ALLOC_FAIL;
never executed: return -2;
0
115 mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);-
116 } else {
never executed: end of block
0
117 mac->mac_len = macalg->len / 8;-
118 mac->key_len = macalg->key_len / 8;-
119 mac->umac_ctx = NULL;-
120 }
never executed: end of block
0
121 if (macalg->truncatebits != 0)
macalg->truncatebits != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
122 mac->mac_len = macalg->truncatebits / 8;
never executed: mac->mac_len = macalg->truncatebits / 8;
0
123 mac->etm = macalg->etm;-
124 return 0;
never executed: return 0;
0
125}-
126-
127int-
128mac_setup(struct sshmac *mac, char *name)-
129{-
130 const struct macalg *m;-
131-
132 for (m = macs; m->name != NULL; m++) {
m->name != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
133 if (strcmp(name, m->name) != 0)
never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( m->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
134 continue;
never executed: continue;
0
135 if (mac != NULL)
mac != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
136 return mac_setup_by_alg(mac, m);
never executed: return mac_setup_by_alg(mac, m);
0
137 return 0;
never executed: return 0;
0
138 }-
139 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
140}-
141-
142int-
143mac_init(struct sshmac *mac)-
144{-
145 if (mac->key == NULL)
mac->key == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
146 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
147 switch (mac->type) {-
148 case SSH_DIGEST:
never executed: case 1:
0
149 if (mac->hmac_ctx == NULL ||
mac->hmac_ctx == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
150 ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
ssh_hmac_init(...->key_len) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
151 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
152 return 0;
never executed: return 0;
0
153 case SSH_UMAC:
never executed: case 2:
0
154 if ((mac->umac_ctx = umac_new(mac->key)) == NULL)
(mac->umac_ctx...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
155 return SSH_ERR_ALLOC_FAIL;
never executed: return -2;
0
156 return 0;
never executed: return 0;
0
157 case SSH_UMAC128:
never executed: case 3:
0
158 if ((mac->umac_ctx = umac128_new(mac->key)) == NULL)
(mac->umac_ctx...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
159 return SSH_ERR_ALLOC_FAIL;
never executed: return -2;
0
160 return 0;
never executed: return 0;
0
161 default:
never executed: default:
0
162 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
163 }-
164}-
165-
166int-
167mac_compute(struct sshmac *mac, u_int32_t seqno,-
168 const u_char *data, int datalen,-
169 u_char *digest, size_t dlen)-
170{-
171 static union {-
172 u_char m[SSH_DIGEST_MAX_LENGTH];-
173 u_int64_t for_align;-
174 } u;-
175 u_char b[4];-
176 u_char nonce[8];-
177-
178 if (mac->mac_len > sizeof(u))
mac->mac_len > sizeof(u)Description
TRUEnever evaluated
FALSEnever evaluated
0
179 return SSH_ERR_INTERNAL_ERROR;
never executed: return -1;
0
180-
181 switch (mac->type) {-
182 case SSH_DIGEST:
never executed: case 1:
0
183 put_u32(b, seqno);-
184 /* reset HMAC context */-
185 if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 ||
ssh_hmac_init(... *)0) , 0) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
186 ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||
ssh_hmac_updat...sizeof(b)) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
187 ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||
ssh_hmac_updat..., datalen) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
188 ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
ssh_hmac_final...zeof(u.m)) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
189 return SSH_ERR_LIBCRYPTO_ERROR;
never executed: return -22;
0
190 break;
never executed: break;
0
191 case SSH_UMAC:
never executed: case 2:
0
192 POKE_U64(nonce, seqno);-
193 umac_update(mac->umac_ctx, data, datalen);-
194 umac_final(mac->umac_ctx, u.m, nonce);-
195 break;
never executed: break;
0
196 case SSH_UMAC128:
never executed: case 3:
0
197 put_u64(nonce, seqno);-
198 umac128_update(mac->umac_ctx, data, datalen);-
199 umac128_final(mac->umac_ctx, u.m, nonce);-
200 break;
never executed: break;
0
201 default:
never executed: default:
0
202 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
203 }-
204 if (digest != NULL) {
digest != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
205 if (dlen > mac->mac_len)
dlen > mac->mac_lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
206 dlen = mac->mac_len;
never executed: dlen = mac->mac_len;
0
207 memcpy(digest, u.m, dlen);-
208 }
never executed: end of block
0
209 return 0;
never executed: return 0;
0
210}-
211-
212int-
213mac_check(struct sshmac *mac, u_int32_t seqno,-
214 const u_char *data, size_t dlen,-
215 const u_char *theirmac, size_t mlen)-
216{-
217 u_char ourmac[SSH_DIGEST_MAX_LENGTH];-
218 int r;-
219-
220 if (mac->mac_len > mlen)
mac->mac_len > mlenDescription
TRUEnever evaluated
FALSEnever evaluated
0
221 return SSH_ERR_INVALID_ARGUMENT;
never executed: return -10;
0
222 if ((r = mac_compute(mac, seqno, data, dlen,
(r = mac_compu...ourmac))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
223 ourmac, sizeof(ourmac))) != 0)
(r = mac_compu...ourmac))) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
224 return r;
never executed: return r;
0
225 if (timingsafe_bcmp(ourmac, theirmac, mac->mac_len) != 0)
timingsafe_bcm...>mac_len) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
226 return SSH_ERR_MAC_INVALID;
never executed: return -30;
0
227 return 0;
never executed: return 0;
0
228}-
229-
230void-
231mac_clear(struct sshmac *mac)-
232{-
233 if (mac->type == SSH_UMAC) {
mac->type == 2Description
TRUEnever evaluated
FALSEevaluated 704 times by 1 test
Evaluated by:
  • test_kex
0-704
234 if (mac->umac_ctx != NULL)
mac->umac_ctx != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
235 umac_delete(mac->umac_ctx);
never executed: umac_delete(mac->umac_ctx);
0
236 } else if (mac->type == SSH_UMAC128) {
never executed: end of block
mac->type == 3Description
TRUEnever evaluated
FALSEevaluated 704 times by 1 test
Evaluated by:
  • test_kex
0-704
237 if (mac->umac_ctx != NULL)
mac->umac_ctx != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
238 umac128_delete(mac->umac_ctx);
never executed: umac128_delete(mac->umac_ctx);
0
239 } else if (mac->hmac_ctx != NULL)
never executed: end of block
mac->hmac_ctx != ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 704 times by 1 test
Evaluated by:
  • test_kex
0-704
240 ssh_hmac_free(mac->hmac_ctx);
never executed: ssh_hmac_free(mac->hmac_ctx);
0
241 mac->hmac_ctx = NULL;-
242 mac->umac_ctx = NULL;-
243}
executed 704 times by 1 test: end of block
Executed by:
  • test_kex
704
244-
245/* XXX copied from ciphers_valid */-
246#define MAC_SEP ","-
247int-
248mac_valid(const char *names)-
249{-
250 char *maclist, *cp, *p;-
251-
252 if (names == NULL || strcmp(names, "") == 0)
never executed: __result = (((const unsigned char *) (const char *) ( names ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
names == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__extension__ ... )))); }) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
253 return 0;
never executed: return 0;
0
254 if ((maclist = cp = strdup(names)) == NULL)
never executed: __retval = (char *) memcpy (__retval, names , __len);
(maclist = cp ...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__retval != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
((const char *... ))[0] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( names )Description
TRUEnever evaluated
FALSEnever evaluated
((size_t)(cons... names ) == 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
255 return 0;
never executed: return 0;
0
256 for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
pDescription
TRUEnever evaluated
FALSEnever evaluated
*p != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
257 (p = strsep(&cp, MAC_SEP))) {-
258 if (mac_setup(NULL, p) < 0) {
mac_setup( ((v... *)0) , p) < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
259 free(maclist);-
260 return 0;
never executed: return 0;
0
261 }-
262 }
never executed: end of block
0
263 free(maclist);-
264 return 1;
never executed: return 1;
0
265}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2