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
↓ 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
↓ 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;
↓ 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  
↓ 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];
↓ 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