diff options
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/libsmbfs/smb/ctx.c | 8 | ||||
| -rw-r--r-- | usr/src/lib/libsmbfs/smb/rcfile.c | 3 | ||||
| -rw-r--r-- | usr/src/lib/smbclnt/libfknsmb/common/fksmb_sign_pkcs.c | 116 | ||||
| -rw-r--r-- | usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c | 10 |
4 files changed, 124 insertions, 13 deletions
diff --git a/usr/src/lib/libsmbfs/smb/ctx.c b/usr/src/lib/libsmbfs/smb/ctx.c index 3aa67fd5f5..64122e3416 100644 --- a/usr/src/lib/libsmbfs/smb/ctx.c +++ b/usr/src/lib/libsmbfs/smb/ctx.c @@ -1411,10 +1411,16 @@ smb_cf_minauth_from_str(char *str) return (-1); } - +/* + * SMB 2.1 is the oldest SMB2 dialect implemented (we skipped SMB 2.002) + * so if we see a_protocol value of just "2" assume they meant 2.1 + */ static struct nv smbver_table[] = { + { "3.02", SMB2_DIALECT_0302 }, + { "3.0", SMB2_DIALECT_0300 }, { "2.1", SMB2_DIALECT_0210 }, + { "2", SMB2_DIALECT_0210 }, { "1", 1 }, { NULL, 0 } }; diff --git a/usr/src/lib/libsmbfs/smb/rcfile.c b/usr/src/lib/libsmbfs/smb/rcfile.c index d7ee2d15af..da96b13c34 100644 --- a/usr/src/lib/libsmbfs/smb/rcfile.c +++ b/usr/src/lib/libsmbfs/smb/rcfile.c @@ -492,8 +492,7 @@ rc_parse(struct rcfile *rcp) if (home_nsmbrc != 0 && ( strcmp(buf, "nbns") == 0 || strcmp(buf, "nbns_enable") == 0 || - strcmp(buf, "nbns_broadcast") == 0 || - strcmp(buf, "signing") == 0)) { + strcmp(buf, "nbns_broadcast") == 0)) { fprintf(stderr, dgettext(TEXT_DOMAIN, "option %s may not be set " "in user .nsmbrc file\n"), buf); diff --git a/usr/src/lib/smbclnt/libfknsmb/common/fksmb_sign_pkcs.c b/usr/src/lib/smbclnt/libfknsmb/common/fksmb_sign_pkcs.c index 24bb8fccbc..44c6666313 100644 --- a/usr/src/lib/smbclnt/libfknsmb/common/fksmb_sign_pkcs.c +++ b/usr/src/lib/smbclnt/libfknsmb/common/fksmb_sign_pkcs.c @@ -23,22 +23,46 @@ #include <stdlib.h> #include <strings.h> +#include <sys/cmn_err.h> #include <netsmb/smb_signing.h> #include <security/cryptoki.h> #include <security/pkcs11.h> /* + * Common function to see if a mech is available. + */ +static int +find_mech(smb_sign_mech_t *mech, ulong_t mid) +{ + CK_SESSION_HANDLE hdl; + CK_RV rv; + + rv = SUNW_C_GetMechSession(mid, &hdl); + if (rv != CKR_OK) { + cmn_err(CE_NOTE, "PKCS#11: no mech 0x%x", + (unsigned int)mid); + return (-1); + } + (void) C_CloseSession(hdl); + + mech->mechanism = mid; + mech->pParameter = NULL; + mech->ulParameterLen = 0; + return (0); +} + +/* * SMB1 signing helpers: * (getmech, init, update, final) */ +/* + * Find out if we have this mech. + */ int smb_md5_getmech(smb_sign_mech_t *mech) { - mech->mechanism = CKM_MD5; - mech->pParameter = NULL; - mech->ulParameterLen = 0; - return (0); + return (find_mech(mech, CKM_MD5)); } /* @@ -93,13 +117,13 @@ smb_md5_final(smb_sign_ctx_t ctx, uint8_t *digest16) * (getmech, init, update, final) */ +/* + * Find out if we have this mech. + */ int smb2_hmac_getmech(smb_sign_mech_t *mech) { - mech->mechanism = CKM_SHA256_HMAC; - mech->pParameter = NULL; - mech->ulParameterLen = 0; - return (0); + return (find_mech(mech, CKM_SHA256_HMAC)); } /* @@ -161,3 +185,79 @@ smb2_hmac_final(smb_sign_ctx_t ctx, uint8_t *digest16) return (rv == CKR_OK ? 0 : -1); } + +/* + * SMB3 signing helpers: + * (getmech, init, update, final) + */ + +/* + * Find out if we have this mech. + */ +int +smb3_cmac_getmech(smb_sign_mech_t *mech) +{ + return (find_mech(mech, CKM_AES_CMAC)); +} + +/* + * Start PKCS#11 session, load the key. + */ +int +smb3_cmac_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech, + uint8_t *key, size_t key_len) +{ + CK_OBJECT_HANDLE hkey = 0; + CK_RV rv; + + rv = SUNW_C_GetMechSession(mech->mechanism, ctxp); + if (rv != CKR_OK) + return (-1); + + rv = SUNW_C_KeyToObject(*ctxp, mech->mechanism, + key, key_len, &hkey); + if (rv != CKR_OK) { + (void) C_CloseSession(*ctxp); + return (-1); + } + + rv = C_SignInit(*ctxp, mech, hkey); + (void) C_DestroyObject(*ctxp, hkey); + if (rv != CKR_OK) { + (void) C_CloseSession(*ctxp); + return (-1); + } + + return (0); +} + +/* + * Digest one segment + */ +int +smb3_cmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len) +{ + CK_RV rv; + + rv = C_SignUpdate(ctx, in, len); + if (rv != CKR_OK) + (void) C_CloseSession(ctx); + + return (rv == CKR_OK ? 0 : -1); +} + +/* + * Note, the SMB2 signature is just the AES CMAC digest. + * (both are 16 bytes long) + */ +int +smb3_cmac_final(smb_sign_ctx_t ctx, uint8_t *digest) +{ + CK_ULONG len = SMB2_SIG_SIZE; + CK_RV rv; + + rv = C_SignFinal(ctx, digest, &len); + (void) C_CloseSession(ctx); + + return (rv == CKR_OK ? 0 : -1); +} diff --git a/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c b/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c index e018c6eb0c..f0eb05093c 100644 --- a/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c +++ b/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c @@ -215,13 +215,19 @@ smb3_cmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech, rv = SUNW_C_KeyToObject(*ctxp, mech->mechanism, key, key_len, &hkey); - if (rv != CKR_OK) + if (rv != CKR_OK) { + (void) C_CloseSession(*ctxp); return (-1); + } rv = C_SignInit(*ctxp, mech, hkey); (void) C_DestroyObject(*ctxp, hkey); + if (rv != CKR_OK) { + (void) C_CloseSession(*ctxp); + return (-1); + } - return (rv == CKR_OK ? 0 : -1); + return (0); } /* |
