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-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>
NEX-3610 CLONE NEX-3591 SMB3 signing
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.c
          +++ new/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_sign_pkcs.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 PKCS#11
  18   18   *
  19   19   * There are two implementations of these functions:
  20   20   * This one (for user space) and another for kernel.
  21   21   * See: uts/common/fs/smbsrv/smb_sign_kcf.c
  22   22   */
  23   23  
  24   24  #include <stdlib.h>
  25   25  #include <smbsrv/smb_kproto.h>
  26      -#include <smbsrv/smb_signing.h>
       26 +#include <smbsrv/smb_kcrypt.h>
  27   27  #include <security/cryptoki.h>
  28   28  #include <security/pkcs11.h>
  29   29  
  30   30  /*
       31 + * Common function to see if a mech is available.
       32 + */
       33 +static int
       34 +find_mech(smb_crypto_mech_t *mech, ulong_t mid)
       35 +{
       36 +        CK_SESSION_HANDLE hdl;
       37 +        CK_RV rv;
       38 +
       39 +        rv = SUNW_C_GetMechSession(mid, &hdl);
       40 +        if (rv != CKR_OK) {
       41 +                cmn_err(CE_NOTE, "PKCS#11: no mech 0x%x",
       42 +                    (unsigned int)mid);
       43 +                return (-1);
       44 +        }
       45 +        (void) C_CloseSession(hdl);
       46 +
       47 +        mech->mechanism = mid;
       48 +        mech->pParameter = NULL;
       49 +        mech->ulParameterLen = 0;
       50 +        return (0);
       51 +}
       52 +
       53 +/*
  31   54   * SMB1 signing helpers:
  32   55   * (getmech, init, update, final)
  33   56   */
  34   57  
       58 +/*
       59 + * Find out if we have this mech.
       60 + */
  35   61  int
  36      -smb_md5_getmech(smb_sign_mech_t *mech)
       62 +smb_md5_getmech(smb_crypto_mech_t *mech)
  37   63  {
  38      -        mech->mechanism = CKM_MD5;
  39      -        mech->pParameter = NULL;
  40      -        mech->ulParameterLen = 0;
  41      -        return (0);
       64 +        return (find_mech(mech, CKM_MD5));
  42   65  }
  43   66  
  44   67  /*
  45   68   * Start PKCS#11 session.
  46   69   */
  47   70  int
  48      -smb_md5_init(smb_sign_ctx_t *ctxp, smb_sign_mech_t *mech)
       71 +smb_md5_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech)
  49   72  {
  50   73          CK_RV rv;
  51   74  
  52   75          rv = SUNW_C_GetMechSession(mech->mechanism, ctxp);
  53   76          if (rv != CKR_OK)
  54   77                  return (-1);
  55   78  
  56   79          rv = C_DigestInit(*ctxp, mech);
  57   80  
  58   81          return (rv == CKR_OK ? 0 : -1);
  59   82  }
  60   83  
  61   84  /*
  62   85   * Digest one segment
  63   86   */
  64   87  int
  65   88  smb_md5_update(smb_sign_ctx_t ctx, void *buf, size_t len)
  66   89  {
  67   90          CK_RV rv;
  68   91  
  69   92          rv = C_DigestUpdate(ctx, buf, len);
  70   93          if (rv != CKR_OK)
  71   94                  (void) C_CloseSession(ctx);
  72   95  
  73   96          return (rv == CKR_OK ? 0 : -1);
  74   97  }
  75   98  
  76   99  /*
  77  100   * Get the final digest.
  78  101   */
  79  102  int
  80  103  smb_md5_final(smb_sign_ctx_t ctx, uint8_t *digest16)
  81  104  {
  82  105          CK_ULONG len = MD5_DIGEST_LENGTH;
  83  106          CK_RV rv;
  84  107  
  85  108          rv = C_DigestFinal(ctx, digest16, &len);
  
    | 
      ↓ open down ↓ | 
    27 lines elided | 
    
      ↑ open up ↑ | 
  
  86  109          (void) C_CloseSession(ctx);
  87  110  
  88  111          return (rv == CKR_OK ? 0 : -1);
  89  112  }
  90  113  
  91  114  /*
  92  115   * SMB2 signing helpers:
  93  116   * (getmech, init, update, final)
  94  117   */
  95  118  
      119 +/*
      120 + * Find out if we have this mech.
      121 + */
  96  122  int
  97      -smb2_hmac_getmech(smb_sign_mech_t *mech)
      123 +smb2_hmac_getmech(smb_crypto_mech_t *mech)
  98  124  {
  99      -        mech->mechanism = CKM_SHA256_HMAC;
 100      -        mech->pParameter = NULL;
 101      -        mech->ulParameterLen = 0;
 102      -        return (0);
      125 +        return (find_mech(mech, CKM_SHA256_HMAC));
 103  126  }
 104  127  
 105  128  /*
 106  129   * Start PKCS#11 session, load the key.
 107  130   */
 108  131  int
 109      -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,
 110  133      uint8_t *key, size_t key_len)
 111  134  {
 112  135          CK_OBJECT_HANDLE hkey = 0;
 113  136          CK_RV rv;
 114  137  
 115  138          rv = SUNW_C_GetMechSession(mech->mechanism, ctxp);
 116  139          if (rv != CKR_OK)
 117  140                  return (-1);
 118  141  
 119  142          rv = SUNW_C_KeyToObject(*ctxp, mech->mechanism,
 120  143              key, key_len, &hkey);
 121  144          if (rv != CKR_OK)
 122  145                  return (-1);
 123  146  
 124  147          rv = C_SignInit(*ctxp, mech, hkey);
 125  148          (void) C_DestroyObject(*ctxp, hkey);
 126  149  
 127  150          return (rv == CKR_OK ? 0 : -1);
 128  151  }
 129  152  
 130  153  /*
 131  154   * Digest one segment
 132  155   */
 133  156  int
 134  157  smb2_hmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len)
 135  158  {
 136  159          CK_RV rv;
 137  160  
 138  161          rv = C_SignUpdate(ctx, in, len);
 139  162          if (rv != CKR_OK)
 140  163                  (void) C_CloseSession(ctx);
 141  164  
 142  165          return (rv == CKR_OK ? 0 : -1);
 143  166  }
 144  167  
 145  168  /*
 146  169   * Note, the SMB2 signature is the first 16 bytes of the
 147  170   * 32-byte SHA256 HMAC digest.
 148  171   */
 149  172  int
 150  173  smb2_hmac_final(smb_sign_ctx_t ctx, uint8_t *digest16)
 151  174  {
  
    | 
      ↓ open down ↓ | 
    32 lines elided | 
    
      ↑ open up ↑ | 
  
 152  175          uint8_t full_digest[SHA256_DIGEST_LENGTH];
 153  176          CK_ULONG len = SHA256_DIGEST_LENGTH;
 154  177          CK_RV rv;
 155  178  
 156  179          rv = C_SignFinal(ctx, full_digest, &len);
 157  180          if (rv == CKR_OK)
 158  181                  bcopy(full_digest, digest16, 16);
 159  182  
 160  183          (void) C_CloseSession(ctx);
 161  184  
      185 +        return (rv == CKR_OK ? 0 : -1);
      186 +}
      187 +
      188 +/*
      189 + * SMB3 signing helpers:
      190 + * (getmech, init, update, final)
      191 + */
      192 +
      193 +/*
      194 + * Find out if we have this mech.
      195 + */
      196 +int
      197 +smb3_cmac_getmech(smb_crypto_mech_t *mech)
      198 +{
      199 +        return (find_mech(mech, CKM_AES_CMAC));
      200 +}
      201 +
      202 +/*
      203 + * Start PKCS#11 session, load the key.
      204 + */
      205 +int
      206 +smb3_cmac_init(smb_sign_ctx_t *ctxp, smb_crypto_mech_t *mech,
      207 +    uint8_t *key, size_t key_len)
      208 +{
      209 +        CK_OBJECT_HANDLE hkey = 0;
      210 +        CK_RV rv;
      211 +
      212 +        rv = SUNW_C_GetMechSession(mech->mechanism, ctxp);
      213 +        if (rv != CKR_OK)
      214 +                return (-1);
      215 +
      216 +        rv = SUNW_C_KeyToObject(*ctxp, mech->mechanism,
      217 +            key, key_len, &hkey);
      218 +        if (rv != CKR_OK)
      219 +                return (-1);
      220 +
      221 +        rv = C_SignInit(*ctxp, mech, hkey);
      222 +        (void) C_DestroyObject(*ctxp, hkey);
      223 +
      224 +        return (rv == CKR_OK ? 0 : -1);
      225 +}
      226 +
      227 +/*
      228 + * Digest one segment
      229 + */
      230 +int
      231 +smb3_cmac_update(smb_sign_ctx_t ctx, uint8_t *in, size_t len)
      232 +{
      233 +        CK_RV rv;
      234 +
      235 +        rv = C_SignUpdate(ctx, in, len);
      236 +        if (rv != CKR_OK)
      237 +                (void) C_CloseSession(ctx);
      238 +
      239 +        return (rv == CKR_OK ? 0 : -1);
      240 +}
      241 +
      242 +/*
      243 + * Note, the SMB2 signature is just the AES CMAC digest.
      244 + * (both are 16 bytes long)
      245 + */
      246 +int
      247 +smb3_cmac_final(smb_sign_ctx_t ctx, uint8_t *digest)
      248 +{
      249 +        CK_ULONG len = SMB2_SIG_SIZE;
      250 +        CK_RV rv;
      251 +
      252 +        rv = C_SignFinal(ctx, digest, &len);
      253 +        (void) C_CloseSession(ctx);
      254 +
 162  255          return (rv == CKR_OK ? 0 : -1);
 163  256  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX