Unleashed v1.4
[unleashed.git] / usr / src / uts / common / fs / smbsrv / smb_sign_kcf.c
blobb016fc197358380a286328523bfb640b68107ff3
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
17 * Helper functions for SMB signing using the
18 * Kernel Cryptographic Framework (KCF)
21 #include <sys/types.h>
22 #include <sys/kmem.h>
23 #include <sys/crypto/api.h>
24 #include <smbsrv/smb_kproto.h>
25 #include <smbsrv/smb_signing.h>
28 * SMB1 signing helpers:
29 * (getmech, init, update, final)
32 int
33 smb_md5_getmech(smb_sign_mech_t *mech)
35 crypto_mech_type_t t;
37 t = crypto_mech2id(SUN_CKM_MD5);
38 if (t == CRYPTO_MECH_INVALID)
39 return (-1);
40 mech->cm_type = t;
41 return (0);
45 * Start the KCF session, load the key
47 int
48 smb_md5_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech)
50 int rv;
52 rv = crypto_digest_init(mech, ctxp, NULL);
54 return (rv == CRYPTO_SUCCESS ? 0 : -1);
58 * Digest one segment
60 int
61 smb_md5_update(smb_sign_ctx_t ctx, void *buf, size_t len)
63 crypto_data_t data;
64 int rv;
66 bzero(&data, sizeof (data));
67 data.cd_format = CRYPTO_DATA_RAW;
68 data.cd_length = len;
69 data.cd_raw.iov_base = buf;
70 data.cd_raw.iov_len = len;
72 rv = crypto_digest_update(ctx, &data, 0);
74 return (rv == CRYPTO_SUCCESS ? 0 : -1);
78 * Get the final digest.
80 int
81 smb_md5_final(smb_sign_ctx_t ctx, uint8_t *digest16)
83 crypto_data_t out;
84 int rv;
86 bzero(&out, sizeof (out));
87 out.cd_format = CRYPTO_DATA_RAW;
88 out.cd_length = MD5_DIGEST_LENGTH;
89 out.cd_raw.iov_len = MD5_DIGEST_LENGTH;
90 out.cd_raw.iov_base = (void *)digest16;
92 rv = crypto_digest_final(ctx, &out, 0);
94 return (rv == CRYPTO_SUCCESS ? 0 : -1);
98 * SMB2 signing helpers:
99 * (getmech, init, update, final)
103 smb2_hmac_getmech(smb_sign_mech_t *mech)
105 crypto_mech_type_t t;
107 t = crypto_mech2id(SUN_CKM_SHA256_HMAC);
108 if (t == CRYPTO_MECH_INVALID)
109 return (-1);
110 mech->cm_type = t;
111 return (0);
115 * Start the KCF session, load the key
118 smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech,
119 uint8_t *key, size_t key_len)
121 crypto_key_t ckey;
122 int rv;
124 bzero(&ckey, sizeof (ckey));
125 ckey.ck_format = CRYPTO_KEY_RAW;
126 ckey.ck_data = key;
127 ckey.ck_length = key_len * 8; /* in bits */
129 rv = crypto_mac_init(mech, &ckey, NULL, ctxp, NULL);
131 return (rv == CRYPTO_SUCCESS ? 0 : -1);
135 * Digest one segment
138 smb2_hmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len)
140 crypto_data_t data;
141 int rv;
143 bzero(&data, sizeof (data));
144 data.cd_format = CRYPTO_DATA_RAW;
145 data.cd_length = len;
146 data.cd_raw.iov_base = (void *)in;
147 data.cd_raw.iov_len = len;
149 rv = crypto_mac_update(ctx, &data, 0);
151 return (rv == CRYPTO_SUCCESS ? 0 : -1);
155 * Note, the SMB2 signature is the first 16 bytes of the
156 * 32-byte SHA256 HMAC digest.
159 smb2_hmac_final(smb_sign_ctx_t ctx, uint8_t *digest16)
161 uint8_t full_digest[SHA256_DIGEST_LENGTH];
162 crypto_data_t out;
163 int rv;
165 bzero(&out, sizeof (out));
166 out.cd_format = CRYPTO_DATA_RAW;
167 out.cd_length = SHA256_DIGEST_LENGTH;
168 out.cd_raw.iov_len = SHA256_DIGEST_LENGTH;
169 out.cd_raw.iov_base = (void *)full_digest;
171 rv = crypto_mac_final(ctx, &out, 0);
172 if (rv == CRYPTO_SUCCESS)
173 bcopy(full_digest, digest16, 16);
175 return (rv == CRYPTO_SUCCESS ? 0 : -1);