1*8329232eSGordon Ross /* 2*8329232eSGordon Ross * This file and its contents are supplied under the terms of the 3*8329232eSGordon Ross * Common Development and Distribution License ("CDDL"), version 1.0. 4*8329232eSGordon Ross * You may only use this file in accordance with the terms of version 5*8329232eSGordon Ross * 1.0 of the CDDL. 6*8329232eSGordon Ross * 7*8329232eSGordon Ross * A full copy of the text of the CDDL should have accompanied this 8*8329232eSGordon Ross * source. A copy of the CDDL is also available via the Internet at 9*8329232eSGordon Ross * http://www.illumos.org/license/CDDL. 10*8329232eSGordon Ross */ 11*8329232eSGordon Ross 12*8329232eSGordon Ross /* 13*8329232eSGordon Ross * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 14*8329232eSGordon Ross */ 15*8329232eSGordon Ross 16*8329232eSGordon Ross /* 17*8329232eSGordon Ross * Helper functions for SMB signing using PKCS#11 18*8329232eSGordon Ross * 19*8329232eSGordon Ross * There are two implementations of these functions: 20*8329232eSGordon Ross * This one (for user space) and another for kernel. 21*8329232eSGordon Ross * See: uts/common/fs/smbclnt/netsmb/smb_sign_kcf.c 22*8329232eSGordon Ross */ 23*8329232eSGordon Ross 24*8329232eSGordon Ross #include <stdlib.h> 25*8329232eSGordon Ross #include <strings.h> 26*8329232eSGordon Ross #include <netsmb/smb_signing.h> 27*8329232eSGordon Ross #include <security/cryptoki.h> 28*8329232eSGordon Ross #include <security/pkcs11.h> 29*8329232eSGordon Ross 30*8329232eSGordon Ross /* 31*8329232eSGordon Ross * SMB1 signing helpers: 32*8329232eSGordon Ross * (getmech, init, update, final) 33*8329232eSGordon Ross */ 34*8329232eSGordon Ross 35*8329232eSGordon Ross int 36*8329232eSGordon Ross smb_md5_getmech(smb_sign_mech_t *mech) 37*8329232eSGordon Ross { 38*8329232eSGordon Ross mech->mechanism = CKM_MD5; 39*8329232eSGordon Ross mech->pParameter = NULL; 40*8329232eSGordon Ross mech->ulParameterLen = 0; 41*8329232eSGordon Ross return (0); 42*8329232eSGordon Ross } 43*8329232eSGordon Ross 44*8329232eSGordon Ross /* 45*8329232eSGordon Ross * Start PKCS#11 session. 46*8329232eSGordon Ross */ 47*8329232eSGordon Ross int 48*8329232eSGordon Ross smb_md5_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech) 49*8329232eSGordon Ross { 50*8329232eSGordon Ross CK_RV rv; 51*8329232eSGordon Ross 52*8329232eSGordon Ross rv = SUNW_C_GetMechSession(mech->mechanism, ctxp); 53*8329232eSGordon Ross if (rv != CKR_OK) 54*8329232eSGordon Ross return (-1); 55*8329232eSGordon Ross 56*8329232eSGordon Ross rv = C_DigestInit(*ctxp, mech); 57*8329232eSGordon Ross 58*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 59*8329232eSGordon Ross } 60*8329232eSGordon Ross 61*8329232eSGordon Ross /* 62*8329232eSGordon Ross * Digest one segment 63*8329232eSGordon Ross */ 64*8329232eSGordon Ross int 65*8329232eSGordon Ross smb_md5_update(smb_sign_ctx_t ctx, void *buf, size_t len) 66*8329232eSGordon Ross { 67*8329232eSGordon Ross CK_RV rv; 68*8329232eSGordon Ross 69*8329232eSGordon Ross rv = C_DigestUpdate(ctx, buf, len); 70*8329232eSGordon Ross if (rv != CKR_OK) 71*8329232eSGordon Ross (void) C_CloseSession(ctx); 72*8329232eSGordon Ross 73*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 74*8329232eSGordon Ross } 75*8329232eSGordon Ross 76*8329232eSGordon Ross /* 77*8329232eSGordon Ross * Get the final digest. 78*8329232eSGordon Ross */ 79*8329232eSGordon Ross int 80*8329232eSGordon Ross smb_md5_final(smb_sign_ctx_t ctx, uint8_t *digest16) 81*8329232eSGordon Ross { 82*8329232eSGordon Ross CK_ULONG len = MD5_DIGEST_LENGTH; 83*8329232eSGordon Ross CK_RV rv; 84*8329232eSGordon Ross 85*8329232eSGordon Ross rv = C_DigestFinal(ctx, digest16, &len); 86*8329232eSGordon Ross (void) C_CloseSession(ctx); 87*8329232eSGordon Ross 88*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 89*8329232eSGordon Ross } 90*8329232eSGordon Ross 91*8329232eSGordon Ross /* 92*8329232eSGordon Ross * SMB2 signing helpers: 93*8329232eSGordon Ross * (getmech, init, update, final) 94*8329232eSGordon Ross */ 95*8329232eSGordon Ross 96*8329232eSGordon Ross int 97*8329232eSGordon Ross smb2_hmac_getmech(smb_sign_mech_t *mech) 98*8329232eSGordon Ross { 99*8329232eSGordon Ross mech->mechanism = CKM_SHA256_HMAC; 100*8329232eSGordon Ross mech->pParameter = NULL; 101*8329232eSGordon Ross mech->ulParameterLen = 0; 102*8329232eSGordon Ross return (0); 103*8329232eSGordon Ross } 104*8329232eSGordon Ross 105*8329232eSGordon Ross /* 106*8329232eSGordon Ross * Start PKCS#11 session, load the key. 107*8329232eSGordon Ross */ 108*8329232eSGordon Ross int 109*8329232eSGordon Ross smb2_hmac_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech, 110*8329232eSGordon Ross uint8_t *key, size_t key_len) 111*8329232eSGordon Ross { 112*8329232eSGordon Ross CK_OBJECT_HANDLE hkey = 0; 113*8329232eSGordon Ross CK_RV rv; 114*8329232eSGordon Ross 115*8329232eSGordon Ross rv = SUNW_C_GetMechSession(mech->mechanism, ctxp); 116*8329232eSGordon Ross if (rv != CKR_OK) 117*8329232eSGordon Ross return (-1); 118*8329232eSGordon Ross 119*8329232eSGordon Ross rv = SUNW_C_KeyToObject(*ctxp, mech->mechanism, 120*8329232eSGordon Ross key, key_len, &hkey); 121*8329232eSGordon Ross if (rv != CKR_OK) 122*8329232eSGordon Ross return (-1); 123*8329232eSGordon Ross 124*8329232eSGordon Ross rv = C_SignInit(*ctxp, mech, hkey); 125*8329232eSGordon Ross (void) C_DestroyObject(*ctxp, hkey); 126*8329232eSGordon Ross 127*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 128*8329232eSGordon Ross } 129*8329232eSGordon Ross 130*8329232eSGordon Ross /* 131*8329232eSGordon Ross * Digest one segment 132*8329232eSGordon Ross */ 133*8329232eSGordon Ross int 134*8329232eSGordon Ross smb2_hmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len) 135*8329232eSGordon Ross { 136*8329232eSGordon Ross CK_RV rv; 137*8329232eSGordon Ross 138*8329232eSGordon Ross rv = C_SignUpdate(ctx, in, len); 139*8329232eSGordon Ross if (rv != CKR_OK) 140*8329232eSGordon Ross (void) C_CloseSession(ctx); 141*8329232eSGordon Ross 142*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 143*8329232eSGordon Ross } 144*8329232eSGordon Ross 145*8329232eSGordon Ross /* 146*8329232eSGordon Ross * Note, the SMB2 signature is the first 16 bytes of the 147*8329232eSGordon Ross * 32-byte SHA256 HMAC digest. 148*8329232eSGordon Ross */ 149*8329232eSGordon Ross int 150*8329232eSGordon Ross smb2_hmac_final(smb_sign_ctx_t ctx, uint8_t *digest16) 151*8329232eSGordon Ross { 152*8329232eSGordon Ross uint8_t full_digest[SHA256_DIGEST_LENGTH]; 153*8329232eSGordon Ross CK_ULONG len = SHA256_DIGEST_LENGTH; 154*8329232eSGordon Ross CK_RV rv; 155*8329232eSGordon Ross 156*8329232eSGordon Ross rv = C_SignFinal(ctx, full_digest, &len); 157*8329232eSGordon Ross if (rv == CKR_OK) 158*8329232eSGordon Ross bcopy(full_digest, digest16, 16); 159*8329232eSGordon Ross 160*8329232eSGordon Ross (void) C_CloseSession(ctx); 161*8329232eSGordon Ross 162*8329232eSGordon Ross return (rv == CKR_OK ? 0 : -1); 163*8329232eSGordon Ross } 164