Select one of the symbols to view example projects that use it.
 
Outline
#include "includes.h"
#include "common.h"
#include "sha1.h"
#include "md5.h"
tls_prf_sha1_md5(const u8 *, size_t, const char *, const u8 *, size_t, u8 *, size_t)
Files
loading...
SourceVuESP-IDF Framework and ExamplesESP-IDFcomponents/wpa_supplicant/src/crypto/sha1-tlsprf.c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * TLS PRF (SHA1 + MD5) * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. *//* ... */ #include "includes.h" #include "common.h" #include "sha1.h" #include "md5.h" /** * tls_prf_sha1_md5 - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246) * @secret: Key for PRF * @secret_len: Length of the key in bytes * @label: A unique label for each purpose of the PRF * @seed: Seed value to bind into the key * @seed_len: Length of the seed * @out: Buffer for the generated pseudo-random key * @outlen: Number of bytes of key to generate * Returns: 0 on success, -1 on failure. * * This function is used to derive new, cryptographically separate keys from a * given key in TLS. This PRF is defined in RFC 2246, Chapter 5. *//* ... */ int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label, const u8 *seed, size_t seed_len, u8 *out, size_t outlen) { size_t L_S1, L_S2, i; const u8 *S1, *S2; u8 A_MD5[MD5_MAC_LEN], A_SHA1[SHA1_MAC_LEN]; u8 P_MD5[MD5_MAC_LEN], P_SHA1[SHA1_MAC_LEN]; int MD5_pos, SHA1_pos; const u8 *MD5_addr[3]; size_t MD5_len[3]; const unsigned char *SHA1_addr[3]; size_t SHA1_len[3]; MD5_addr[0] = A_MD5; MD5_len[0] = MD5_MAC_LEN; MD5_addr[1] = (unsigned char *) label; MD5_len[1] = os_strlen(label); MD5_addr[2] = seed; MD5_len[2] = seed_len; SHA1_addr[0] = A_SHA1; SHA1_len[0] = SHA1_MAC_LEN; SHA1_addr[1] = (unsigned char *) label; SHA1_len[1] = os_strlen(label); SHA1_addr[2] = seed; SHA1_len[2] = seed_len; /* RFC 2246, Chapter 5 * A(0) = seed, A(i) = HMAC(secret, A(i-1)) * P_hash = HMAC(secret, A(1) + seed) + HMAC(secret, A(2) + seed) + .. * PRF = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed) *//* ... */ L_S1 = L_S2 = (secret_len + 1) / 2; S1 = secret; S2 = secret + L_S1; if (secret_len & 1) { /* The last byte of S1 will be shared with S2 */ S2--; }{...} hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5); hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1); MD5_pos = MD5_MAC_LEN; SHA1_pos = SHA1_MAC_LEN; for (i = 0; i < outlen; i++) { if (MD5_pos == MD5_MAC_LEN) { hmac_md5_vector(S1, L_S1, 3, MD5_addr, MD5_len, P_MD5); MD5_pos = 0; hmac_md5(S1, L_S1, A_MD5, MD5_MAC_LEN, A_MD5); }{...} if (SHA1_pos == SHA1_MAC_LEN) { hmac_sha1_vector(S2, L_S2, 3, SHA1_addr, SHA1_len, P_SHA1); SHA1_pos = 0; hmac_sha1(S2, L_S2, A_SHA1, SHA1_MAC_LEN, A_SHA1); }{...} out[i] = P_MD5[MD5_pos] ^ P_SHA1[SHA1_pos]; MD5_pos++; SHA1_pos++; }{...} forced_memzero(A_MD5, MD5_MAC_LEN); forced_memzero(P_MD5, MD5_MAC_LEN); forced_memzero(A_SHA1, SHA1_MAC_LEN); forced_memzero(P_SHA1, SHA1_MAC_LEN); return 0; }{ ... }
Details