OpenCoverage

bcrypt_pbkdf.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/openbsd-compat/bcrypt_pbkdf.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */-
2/*-
3 * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>-
4 *-
5 * Permission to use, copy, modify, and distribute this software for any-
6 * purpose with or without fee is hereby granted, provided that the above-
7 * copyright notice and this permission notice appear in all copies.-
8 *-
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR-
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN-
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF-
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
16 */-
17-
18#include "includes.h"-
19-
20#ifndef HAVE_BCRYPT_PBKDF-
21-
22#include <sys/types.h>-
23#include <sys/param.h>-
24-
25#ifdef HAVE_STDLIB_H-
26# include <stdlib.h>-
27#endif-
28#include <string.h>-
29-
30#ifdef HAVE_BLF_H-
31# include <blf.h>-
32#endif-
33-
34#include "crypto_api.h"-
35#ifdef SHA512_DIGEST_LENGTH-
36# undef SHA512_DIGEST_LENGTH-
37#endif-
38#define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES-
39-
40#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))-
41-
42/*-
43 * pkcs #5 pbkdf2 implementation using the "bcrypt" hash-
44 *-
45 * The bcrypt hash function is derived from the bcrypt password hashing-
46 * function with the following modifications:-
47 * 1. The input password and salt are preprocessed with SHA512.-
48 * 2. The output length is expanded to 256 bits.-
49 * 3. Subsequently the magic string to be encrypted is lengthened and modified-
50 * to "OxychromaticBlowfishSwatDynamite"-
51 * 4. The hash function is defined to perform 64 rounds of initial state-
52 * expansion. (More rounds are performed by iterating the hash.)-
53 *-
54 * Note that this implementation pulls the SHA512 operations into the caller-
55 * as a performance optimization.-
56 *-
57 * One modification from official pbkdf2. Instead of outputting key material-
58 * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to-
59 * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an-
60 * attacker can merely run once through the outer loop, but the user-
61 * always runs it twice. Shuffling output bytes requires computing the-
62 * entirety of the key material to assemble any subkey. This is something a-
63 * wise caller could do; we just do it for you.-
64 */-
65-
66#define BCRYPT_WORDS 8-
67#define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4)-
68-
69static void-
70bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out)-
71{-
72 blf_ctx state;-
73 u_int8_t ciphertext[BCRYPT_HASHSIZE] =-
74 "OxychromaticBlowfishSwatDynamite";-
75 uint32_t cdata[BCRYPT_WORDS];-
76 int i;-
77 uint16_t j;-
78 size_t shalen = SHA512_DIGEST_LENGTH;-
79-
80 /* key expansion */-
81 Blowfish_initstate(&state);-
82 Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);-
83 for (i = 0; i < 64; i++) {
i < 64Description
TRUEevaluated 8192 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 128 times by 1 test
Evaluated by:
  • test_sshkey
128-8192
84 Blowfish_expand0state(&state, sha2salt, shalen);-
85 Blowfish_expand0state(&state, sha2pass, shalen);-
86 }
executed 8192 times by 1 test: end of block
Executed by:
  • test_sshkey
8192
87-
88 /* encryption */-
89 j = 0;-
90 for (i = 0; i < BCRYPT_WORDS; i++)
i < 8Description
TRUEevaluated 1024 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 128 times by 1 test
Evaluated by:
  • test_sshkey
128-1024
91 cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
executed 1024 times by 1 test: cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), &j);
Executed by:
  • test_sshkey
1024
92 &j);
executed 1024 times by 1 test: cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), &j);
Executed by:
  • test_sshkey
1024
93 for (i = 0; i < 64; i++)
i < 64Description
TRUEevaluated 8192 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 128 times by 1 test
Evaluated by:
  • test_sshkey
128-8192
94 blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
executed 8192 times by 1 test: blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
Executed by:
  • test_sshkey
8192
95-
96 /* copy out */-
97 for (i = 0; i < BCRYPT_WORDS; i++) {
i < 8Description
TRUEevaluated 1024 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 128 times by 1 test
Evaluated by:
  • test_sshkey
128-1024
98 out[4 * i + 3] = (cdata[i] >> 24) & 0xff;-
99 out[4 * i + 2] = (cdata[i] >> 16) & 0xff;-
100 out[4 * i + 1] = (cdata[i] >> 8) & 0xff;-
101 out[4 * i + 0] = cdata[i] & 0xff;-
102 }
executed 1024 times by 1 test: end of block
Executed by:
  • test_sshkey
1024
103-
104 /* zap */-
105 explicit_bzero(ciphertext, sizeof(ciphertext));-
106 explicit_bzero(cdata, sizeof(cdata));-
107 explicit_bzero(&state, sizeof(state));-
108}
executed 128 times by 1 test: end of block
Executed by:
  • test_sshkey
128
109-
110int-
111bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t saltlen,-
112 u_int8_t *key, size_t keylen, unsigned int rounds)-
113{-
114 u_int8_t sha2pass[SHA512_DIGEST_LENGTH];-
115 u_int8_t sha2salt[SHA512_DIGEST_LENGTH];-
116 u_int8_t out[BCRYPT_HASHSIZE];-
117 u_int8_t tmpout[BCRYPT_HASHSIZE];-
118 u_int8_t *countsalt;-
119 size_t i, j, amt, stride;-
120 uint32_t count;-
121 size_t origkeylen = keylen;-
122-
123 /* nothing crazy */-
124 if (rounds < 1)
rounds < 1Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
0-4
125 return -1;
never executed: return -1;
0
126 if (passlen == 0 || saltlen == 0 || keylen == 0 ||
passlen == 0Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
saltlen == 0Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
keylen == 0Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
0-4
127 keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
keylen > sizeo... * sizeof(out)Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
saltlen > 1<<20Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
0-4
128 return -1;
never executed: return -1;
0
129 if ((countsalt = calloc(1, saltlen + 4)) == NULL)
(countsalt = c...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
0-4
130 return -1;
never executed: return -1;
0
131 stride = (keylen + sizeof(out) - 1) / sizeof(out);-
132 amt = (keylen + stride - 1) / stride;-
133-
134 memcpy(countsalt, salt, saltlen);-
135-
136 /* collapse password */-
137 crypto_hash_sha512(sha2pass, pass, passlen);-
138-
139 /* generate key, sizeof(out) at a time */-
140 for (count = 1; keylen > 0; count++) {
keylen > 0Description
TRUEevaluated 8 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
4-8
141 countsalt[saltlen + 0] = (count >> 24) & 0xff;-
142 countsalt[saltlen + 1] = (count >> 16) & 0xff;-
143 countsalt[saltlen + 2] = (count >> 8) & 0xff;-
144 countsalt[saltlen + 3] = count & 0xff;-
145-
146 /* first round, salt is salt */-
147 crypto_hash_sha512(sha2salt, countsalt, saltlen + 4);-
148-
149 bcrypt_hash(sha2pass, sha2salt, tmpout);-
150 memcpy(out, tmpout, sizeof(out));-
151-
152 for (i = 1; i < rounds; i++) {
i < roundsDescription
TRUEevaluated 120 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 8 times by 1 test
Evaluated by:
  • test_sshkey
8-120
153 /* subsequent rounds, salt is previous output */-
154 crypto_hash_sha512(sha2salt, tmpout, sizeof(tmpout));-
155 bcrypt_hash(sha2pass, sha2salt, tmpout);-
156 for (j = 0; j < sizeof(out); j++)
j < sizeof(out)Description
TRUEevaluated 3840 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 120 times by 1 test
Evaluated by:
  • test_sshkey
120-3840
157 out[j] ^= tmpout[j];
executed 3840 times by 1 test: out[j] ^= tmpout[j];
Executed by:
  • test_sshkey
3840
158 }
executed 120 times by 1 test: end of block
Executed by:
  • test_sshkey
120
159-
160 /*-
161 * pbkdf2 deviation: output the key material non-linearly.-
162 */-
163 amt = MINIMUM(amt, keylen);
((amt) < (keylen))Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 4 times by 1 test
Evaluated by:
  • test_sshkey
4
164 for (i = 0; i < amt; i++) {
i < amtDescription
TRUEevaluated 192 times by 1 test
Evaluated by:
  • test_sshkey
FALSEevaluated 8 times by 1 test
Evaluated by:
  • test_sshkey
8-192
165 size_t dest = i * stride + (count - 1);-
166 if (dest >= origkeylen)
dest >= origkeylenDescription
TRUEnever evaluated
FALSEevaluated 192 times by 1 test
Evaluated by:
  • test_sshkey
0-192
167 break;
never executed: break;
0
168 key[dest] = out[i];-
169 }
executed 192 times by 1 test: end of block
Executed by:
  • test_sshkey
192
170 keylen -= i;-
171 }
executed 8 times by 1 test: end of block
Executed by:
  • test_sshkey
8
172-
173 /* zap */-
174 explicit_bzero(out, sizeof(out));-
175 free(countsalt);-
176-
177 return 0;
executed 4 times by 1 test: return 0;
Executed by:
  • test_sshkey
4
178}-
179#endif /* HAVE_BCRYPT_PBKDF */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2