1 | /* |
2 | * Copyright (c) 2007-2016, Cameron Rich |
3 | * |
4 | * All rights reserved. |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions are met: |
8 | * |
9 | * * Redistributions of source code must retain the above copyright notice, |
10 | * this list of conditions and the following disclaimer. |
11 | * * Redistributions in binary form must reproduce the above copyright notice, |
12 | * this list of conditions and the following disclaimer in the documentation |
13 | * and/or other materials provided with the distribution. |
14 | * * Neither the name of the axTLS project nor the names of its contributors |
15 | * may be used to endorse or promote products derived from this software |
16 | * without specific prior written permission. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ |
30 | |
31 | /** |
32 | * HMAC implementation - This code was originally taken from RFC2104 |
33 | * See http://www.ietf.org/rfc/rfc2104.txt and |
34 | * http://www.faqs.org/rfcs/rfc2202.html |
35 | */ |
36 | |
37 | #include <string.h> |
38 | #include "os_port.h" |
39 | #include "crypto.h" |
40 | |
41 | /** |
42 | * Perform HMAC-MD5 |
43 | * NOTE: does not handle keys larger than the block size. |
44 | */ |
45 | void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key, |
46 | int key_len, uint8_t *digest) |
47 | { |
48 | MD5_CTX context; |
49 | uint8_t k_pad[64]; |
50 | int i; |
51 | |
52 | memset(k_pad, 0, sizeof k_pad); |
53 | memcpy(k_pad, key, key_len); |
54 | for (i = 0; i < 64; i++) |
55 | { |
56 | k_pad[i] ^= 0x36; |
57 | } |
58 | |
59 | MD5_Init(&context); |
60 | MD5_Update(&context, k_pad, 64); |
61 | MD5_Update(&context, msg, length); |
62 | MD5_Final(digest, &context); |
63 | |
64 | memset(k_pad, 0, sizeof k_pad); |
65 | memcpy(k_pad, key, key_len); |
66 | for (i = 0; i < 64; i++) |
67 | { |
68 | k_pad[i] ^= 0x5c; |
69 | } |
70 | |
71 | MD5_Init(&context); |
72 | MD5_Update(&context, k_pad, 64); |
73 | MD5_Update(&context, digest, MD5_SIZE); |
74 | MD5_Final(digest, &context); |
75 | } |
76 | |
77 | /** |
78 | * Perform HMAC-SHA1 |
79 | * NOTE: does not handle keys larger than the block size. |
80 | */ |
81 | void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, |
82 | int key_len, uint8_t *digest) |
83 | { |
84 | SHA1_CTX context; |
85 | uint8_t k_pad[64]; |
86 | int i; |
87 | |
88 | memset(k_pad, 0, sizeof k_pad); |
89 | memcpy(k_pad, key, key_len); |
90 | for (i = 0; i < 64; i++) |
91 | { |
92 | k_pad[i] ^= 0x36; |
93 | } |
94 | |
95 | SHA1_Init(&context); |
96 | SHA1_Update(&context, k_pad, 64); |
97 | SHA1_Update(&context, msg, length); |
98 | SHA1_Final(digest, &context); |
99 | |
100 | memset(k_pad, 0, sizeof k_pad); |
101 | memcpy(k_pad, key, key_len); |
102 | for (i = 0; i < 64; i++) |
103 | { |
104 | k_pad[i] ^= 0x5c; |
105 | } |
106 | |
107 | SHA1_Init(&context); |
108 | SHA1_Update(&context, k_pad, 64); |
109 | SHA1_Update(&context, digest, SHA1_SIZE); |
110 | SHA1_Final(digest, &context); |
111 | } |
112 | |
113 | /** |
114 | * Perform HMAC-SHA256 |
115 | * NOTE: does not handle keys larger than the block size. |
116 | */ |
117 | void hmac_sha256(const uint8_t *msg, int length, const uint8_t *key, |
118 | int key_len, uint8_t *digest) |
119 | { |
120 | SHA256_CTX context; |
121 | uint8_t k_ipad[64]; |
122 | uint8_t k_opad[64]; |
123 | int i; |
124 | |
125 | memset(k_ipad, 0, sizeof k_ipad); |
126 | memset(k_opad, 0, sizeof k_opad); |
127 | memcpy(k_ipad, key, key_len); |
128 | memcpy(k_opad, key, key_len); |
129 | |
130 | for (i = 0; i < 64; i++) |
131 | { |
132 | k_ipad[i] ^= 0x36; |
133 | k_opad[i] ^= 0x5c; |
134 | } |
135 | |
136 | SHA256_Init(&context); |
137 | SHA256_Update(&context, k_ipad, 64); |
138 | SHA256_Update(&context, msg, length); |
139 | SHA256_Final(digest, &context); |
140 | SHA256_Init(&context); |
141 | SHA256_Update(&context, k_opad, 64); |
142 | SHA256_Update(&context, digest, SHA256_SIZE); |
143 | SHA256_Final(digest, &context); |
144 | } |
145 | |
146 | |