annotate src/lib/pkcs5.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents 2e2563132d5f
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21264
diff changeset
1 /* Copyright (c) 2016-2017 Dovecot authors, see the included COPYING file */
21264
8f33680c6722 global: Added missing copyright notices.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20252
diff changeset
2
20252
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
3 #include "lib.h"
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
4 #include "buffer.h"
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
5 #include "hash-method.h"
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
6 #include "hmac.h"
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
7 #include "pkcs5.h"
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
8
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
9 #include <stdint.h>
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
10 #include <arpa/inet.h>
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
11
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
12 static
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
13 int pkcs5_pbkdf1(const struct hash_method *hash,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
14 const unsigned char *password, size_t password_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
15 const unsigned char *salt, size_t salt_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
16 unsigned int iter, uint32_t length,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
17 buffer_t *result)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
18 {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
19 if (length < 1 ||
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
20 length > hash->digest_size) return -1;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
21 if (iter < 1) return -1;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
22
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
23 unsigned char dk[hash->digest_size];
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
24 unsigned char ctx[hash->context_size];
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
25
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
26 hash->init(ctx);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
27 hash->loop(ctx, password, password_len);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
28 hash->loop(ctx, salt, salt_len);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
29 hash->result(ctx, dk);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
30 length--;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
31
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
32 for(;length>0;length--) {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
33 hash->init(ctx);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
34 hash->loop(ctx, dk, hash->digest_size);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
35 hash->result(ctx, dk);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
36 }
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
37
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
38 buffer_append(result, dk, hash->digest_size);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
39
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
40 return 0;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
41 }
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
42
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
43 static
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
44 int pkcs5_pbkdf2(const struct hash_method *hash,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
45 const unsigned char *password, size_t password_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
46 const unsigned char *salt, size_t salt_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
47 unsigned int iter, uint32_t length,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
48 buffer_t *result)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
49 {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
50 if (length < 1 || iter < 1) return -1;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
51
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
52 size_t l = (length + hash->digest_size - 1)/hash->digest_size; /* same as ceil(length/hash->digest_size) */
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
53 unsigned char dk[l * hash->digest_size];
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
54 unsigned char *block;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
55 struct hmac_context hctx;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
56 unsigned int c,i,t;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
57 unsigned char U_c[hash->digest_size];
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
58
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
59 for(t = 0; t < l; t++) {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
60 block = &(dk[t*hash->digest_size]);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
61 /* U_1 = PRF(Password, Salt|| INT_BE32(Block_Number)) */
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
62 c = htonl(t+1);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
63 hmac_init(&hctx, password, password_len, hash);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
64 hmac_update(&hctx, salt, salt_len);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
65 hmac_update(&hctx, &c, sizeof(c));
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
66 hmac_final(&hctx, U_c);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
67 /* block = U_1 ^ .. ^ U_iter */
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
68 memcpy(block, U_c, hash->digest_size);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
69 /* U_c = PRF(Password, U_c-1) */
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
70 for(c = 1; c < iter; c++) {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
71 hmac_init(&hctx, password, password_len, hash);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
72 hmac_update(&hctx, U_c, hash->digest_size);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
73 hmac_final(&hctx, U_c);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
74 for(i = 0; i < hash->digest_size; i++)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
75 block[i] ^= U_c[i];
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
76 }
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
77 }
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
78
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
79 buffer_append(result, dk, length);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
80
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
81 return 0;
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
82 }
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
83
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
84 int pkcs5_pbkdf(enum pkcs5_pbkdf_mode mode, const struct hash_method *hash,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
85 const unsigned char *password, size_t password_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
86 const unsigned char *salt, size_t salt_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
87 unsigned int iterations, uint32_t dk_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
88 buffer_t *result)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
89 {
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
90 if (mode == PKCS5_PBKDF1)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
91 return pkcs5_pbkdf1(hash,password,password_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
92 salt,salt_len,iterations,dk_len,result);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
93 else if (mode == PKCS5_PBKDF2)
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
94 return pkcs5_pbkdf2(hash,password,password_len,
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
95 salt,salt_len,iterations,dk_len,result);
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
96 i_unreached();
2cacbc8e95c5 lib: Add PKCS#5 pbkdf1 and 2
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
97 }