Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-6685 Potential memory leak in SMB KCF wrapper
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-3728 SMB1 signing should use KCF like SMB2/3
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_sign_kcf.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_sign_kcf.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
13 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
14 14 */
15 15
16 16 /*
17 17 * Helper functions for SMB signing using the
18 18 * Kernel Cryptographic Framework (KCF)
19 19 *
20 20 * There are two implementations of these functions:
21 21 * This one (for kernel) and another for user space:
22 22 * See: lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c
23 23 */
24 24
25 25 #include <sys/types.h>
26 26 #include <sys/kmem.h>
27 27 #include <sys/crypto/api.h>
28 28 #include <smbsrv/smb_kproto.h>
29 -#include <smbsrv/smb_signing.h>
29 +#include <smbsrv/smb_kcrypt.h>
30 30
31 31 /*
32 - * SMB1 signing helpers:
33 - * (getmech, init, update, final)
32 + * Common function to see if a mech is available.
34 33 */
35 -
36 -int
37 -smb_md5_getmech(smb_sign_mech_t *mech)
34 +static int
35 +find_mech(smb_crypto_mech_t *mech, crypto_mech_name_t name)
38 36 {
39 37 crypto_mech_type_t t;
40 38
41 - t = crypto_mech2id(SUN_CKM_MD5);
42 - if (t == CRYPTO_MECH_INVALID)
39 + t = crypto_mech2id(name);
40 + if (t == CRYPTO_MECH_INVALID) {
41 + cmn_err(CE_NOTE, "smb: no kcf mech: %s", name);
43 42 return (-1);
43 + }
44 44 mech->cm_type = t;
45 45 return (0);
46 46 }
47 47
48 48 /*
49 + * SMB1 signing helpers:
50 + * (getmech, init, update, final)
51 + */
52 +
53 +int
54 +smb_md5_getmech(smb_crypto_mech_t *mech)
55 +{
56 + return (find_mech(mech, SUN_CKM_MD5));
57 +}
58 +
59 +/*
49 60 * Start the KCF session, load the key
50 61 */
51 62 int
52 -smb_md5_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech)
63 +smb_md5_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech)
53 64 {
54 65 int rv;
55 66
56 67 rv = crypto_digest_init(mech, ctxp, NULL);
57 68
58 69 return (rv == CRYPTO_SUCCESS ? 0 : -1);
59 70 }
60 71
61 72 /*
62 73 * Digest one segment
63 74 */
64 75 int
65 76 smb_md5_update(smb_sign_ctx_t ctx, void *buf, size_t len)
66 77 {
67 78 crypto_data_t data;
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
68 79 int rv;
69 80
70 81 bzero(&data, sizeof (data));
71 82 data.cd_format = CRYPTO_DATA_RAW;
72 83 data.cd_length = len;
73 84 data.cd_raw.iov_base = buf;
74 85 data.cd_raw.iov_len = len;
75 86
76 87 rv = crypto_digest_update(ctx, &data, 0);
77 88
78 - return (rv == CRYPTO_SUCCESS ? 0 : -1);
89 + if (rv != CRYPTO_SUCCESS) {
90 + crypto_cancel_ctx(ctx);
91 + return (-1);
92 + }
93 +
94 + return (0);
79 95 }
80 96
81 97 /*
82 98 * Get the final digest.
83 99 */
84 100 int
85 101 smb_md5_final(smb_sign_ctx_t ctx, uint8_t *digest16)
86 102 {
87 103 crypto_data_t out;
88 104 int rv;
89 105
90 106 bzero(&out, sizeof (out));
91 107 out.cd_format = CRYPTO_DATA_RAW;
92 108 out.cd_length = MD5_DIGEST_LENGTH;
93 109 out.cd_raw.iov_len = MD5_DIGEST_LENGTH;
94 110 out.cd_raw.iov_base = (void *)digest16;
95 111
96 112 rv = crypto_digest_final(ctx, &out, 0);
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
97 113
98 114 return (rv == CRYPTO_SUCCESS ? 0 : -1);
99 115 }
100 116
101 117 /*
102 118 * SMB2 signing helpers:
103 119 * (getmech, init, update, final)
104 120 */
105 121
106 122 int
107 -smb2_hmac_getmech(smb_sign_mech_t *mech)
123 +smb2_hmac_getmech(smb_crypto_mech_t *mech)
108 124 {
109 - crypto_mech_type_t t;
110 -
111 - t = crypto_mech2id(SUN_CKM_SHA256_HMAC);
112 - if (t == CRYPTO_MECH_INVALID)
113 - return (-1);
114 - mech->cm_type = t;
115 - return (0);
125 + return (find_mech(mech, SUN_CKM_SHA256_HMAC));
116 126 }
117 127
118 128 /*
119 129 * Start the KCF session, load the key
120 130 */
121 131 int
122 -smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech,
132 +smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech,
123 133 uint8_t *key, size_t key_len)
124 134 {
125 135 crypto_key_t ckey;
126 136 int rv;
127 137
128 138 bzero(&ckey, sizeof (ckey));
129 139 ckey.ck_format = CRYPTO_KEY_RAW;
130 140 ckey.ck_data = key;
131 141 ckey.ck_length = key_len * 8; /* in bits */
132 142
133 143 rv = crypto_mac_init(mech, &ckey, NULL, ctxp, NULL);
134 144
135 145 return (rv == CRYPTO_SUCCESS ? 0 : -1);
136 146 }
137 147
138 148 /*
139 149 * Digest one segment
140 150 */
141 151 int
142 152 smb2_hmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len)
143 153 {
144 154 crypto_data_t data;
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
145 155 int rv;
146 156
147 157 bzero(&data, sizeof (data));
148 158 data.cd_format = CRYPTO_DATA_RAW;
149 159 data.cd_length = len;
150 160 data.cd_raw.iov_base = (void *)in;
151 161 data.cd_raw.iov_len = len;
152 162
153 163 rv = crypto_mac_update(ctx, &data, 0);
154 164
155 - return (rv == CRYPTO_SUCCESS ? 0 : -1);
165 + if (rv != CRYPTO_SUCCESS) {
166 + crypto_cancel_ctx(ctx);
167 + return (-1);
168 + }
169 +
170 + return (0);
156 171 }
157 172
158 173 /*
159 174 * Note, the SMB2 signature is the first 16 bytes of the
160 175 * 32-byte SHA256 HMAC digest.
161 176 */
162 177 int
163 178 smb2_hmac_final(smb_sign_ctx_t ctx, uint8_t *digest16)
164 179 {
165 180 uint8_t full_digest[SHA256_DIGEST_LENGTH];
166 181 crypto_data_t out;
167 182 int rv;
168 183
169 184 bzero(&out, sizeof (out));
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
170 185 out.cd_format = CRYPTO_DATA_RAW;
171 186 out.cd_length = SHA256_DIGEST_LENGTH;
172 187 out.cd_raw.iov_len = SHA256_DIGEST_LENGTH;
173 188 out.cd_raw.iov_base = (void *)full_digest;
174 189
175 190 rv = crypto_mac_final(ctx, &out, 0);
176 191 if (rv == CRYPTO_SUCCESS)
177 192 bcopy(full_digest, digest16, 16);
178 193
179 194 return (rv == CRYPTO_SUCCESS ? 0 : -1);
195 +}
196 +
197 +/*
198 + * SMB3 signing helpers:
199 + * (getmech, init, update, final)
200 + */
201 +
202 +int
203 +smb3_cmac_getmech(smb_crypto_mech_t *mech)
204 +{
205 + return (find_mech(mech, SUN_CKM_AES_CMAC));
206 +}
207 +
208 +/*
209 + * Start the KCF session, load the key
210 + */
211 +int
212 +smb3_cmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech,
213 + uint8_t *key, size_t key_len)
214 +{
215 + crypto_key_t ckey;
216 + int rv;
217 +
218 + bzero(&ckey, sizeof (ckey));
219 + ckey.ck_format = CRYPTO_KEY_RAW;
220 + ckey.ck_data = key;
221 + ckey.ck_length = key_len * 8; /* in bits */
222 +
223 + rv = crypto_mac_init(mech, &ckey, NULL, ctxp, NULL);
224 +
225 + return (rv == CRYPTO_SUCCESS ? 0 : -1);
226 +}
227 +
228 +/*
229 + * Digest one segment
230 + */
231 +int
232 +smb3_cmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len)
233 +{
234 + crypto_data_t data;
235 + int rv;
236 +
237 + bzero(&data, sizeof (data));
238 + data.cd_format = CRYPTO_DATA_RAW;
239 + data.cd_length = len;
240 + data.cd_raw.iov_base = (void *)in;
241 + data.cd_raw.iov_len = len;
242 +
243 + rv = crypto_mac_update(ctx, &data, 0);
244 +
245 + if (rv != CRYPTO_SUCCESS) {
246 + crypto_cancel_ctx(ctx);
247 + return (-1);
248 + }
249 +
250 + return (0);
251 +}
252 +
253 +/*
254 + * Note, the SMB2 signature is just the AES CMAC digest.
255 + * (both are 16 bytes long)
256 + */
257 +int
258 +smb3_cmac_final(smb_sign_ctx_t ctx, uint8_t *digest16)
259 +{
260 + crypto_data_t out;
261 + int rv;
262 +
263 + bzero(&out, sizeof (out));
264 + out.cd_format = CRYPTO_DATA_RAW;
265 + out.cd_length = SMB2_SIG_SIZE;
266 + out.cd_raw.iov_len = SMB2_SIG_SIZE;
267 + out.cd_raw.iov_base = (void *)digest16;
268 +
269 + rv = crypto_mac_final(ctx, &out, 0);
270 +
271 + return (rv == CRYPTO_SUCCESS ? 0 : -1);
180 272 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX