Print this page
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
          +++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystore.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2018, Joyent, Inc.
  23   24   */
  24   25  
  25   26  #include <crypt.h>
  26   27  #include <cryptoutil.h>
  27   28  #include <pwd.h>
  28   29  #include <pthread.h>
  29   30  #include <stdlib.h>
  30   31  #include <string.h>
  31   32  #include <strings.h>
  32   33  #include <sys/types.h>
↓ open down ↓ 58 lines elided ↑ open up ↑
  91   92                   * on return.  Pass "$5" here to default to crypt_sha256 since
  92   93                   * SHA256 is a FIPS 140-2 certified algorithm and we shouldn't
  93   94                   * assume the system default is that strong.
  94   95                   */
  95   96                  if ((*salt = crypt_gensalt("$5", pw)) == NULL) {
  96   97                          return (-1);
  97   98                  }
  98   99          }
  99  100  
 100  101          if ((*result = crypt((char *)pPin, *salt)) == NULL) {
 101      -                if (new_salt)
 102      -                        free(*salt);
      102 +                if (new_salt) {
      103 +                        size_t saltlen = strlen(*salt) + 1;
      104 +
      105 +                        freezero(*salt, saltlen);
      106 +                }
 103  107                  return (-1);
 104  108          }
 105  109  
 106  110          return (0);
 107  111  }
 108  112  
 109  113  /*
 110  114   * Authenticate user's PIN for C_Login.
 111  115   */
 112  116  CK_RV
 113  117  soft_verify_pin(CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
 114  118  {
 115  119  
 116  120          char    *user_cryptpin = NULL;
 117  121          char    *ks_cryptpin = NULL;
 118  122          char    *salt = NULL;
 119  123          uchar_t *tmp_pin = NULL;
 120  124          boolean_t pin_initialized = B_FALSE;
 121  125          CK_RV   rv = CKR_OK;
      126 +        size_t  len = 0;
 122  127  
 123  128          /*
 124  129           * Check to see if keystore is initialized.
 125  130           */
 126  131          rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 127  132              B_FALSE);
 128  133          if (rv != CKR_OK)
 129  134                  return (rv);
 130  135  
 131  136          /*
↓ open down ↓ 50 lines elided ↑ open up ↑
 182  187                   * We will let it pass the authentication anyway but set the
 183  188                   * "userpin_change_needed" flag so that the application
 184  189                   * will get CKR_PIN_EXPIRED by other C_functions such as
 185  190                   * C_CreateObject, C_FindObjectInit, C_GenerateKey etc.
 186  191                   */
 187  192                  soft_slot.userpin_change_needed = 1;
 188  193                  rv = CKR_OK;
 189  194          }
 190  195  
 191  196  cleanup:
 192      -        if (salt)
 193      -                free(salt);
 194      -        if (tmp_pin)
 195      -                free(tmp_pin);
 196      -        if (ks_cryptpin)
 197      -                free(ks_cryptpin);
 198      -
      197 +        if (salt) {
      198 +                len = strlen(salt) + 1;
      199 +                freezero(salt, len);
      200 +        }
      201 +        if (tmp_pin) {
      202 +                len = strlen((char *)tmp_pin) + 1;
      203 +                freezero(tmp_pin, len);
      204 +        }
      205 +        if (ks_cryptpin) {
      206 +                len = strlen(ks_cryptpin) + 1;
      207 +                freezero(ks_cryptpin, len);
      208 +        }
 199  209          return (rv);
 200  210  }
 201  211  
 202  212  /*
 203  213   * The second level C_SetPIN function.
 204  214   */
 205  215  CK_RV
 206  216  soft_setpin(CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen,
 207  217      CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen)
 208  218  {
 209  219  
 210  220          char    *user_cryptpin = NULL;
 211  221          char    *ks_cryptpin = NULL;
 212  222          char    *salt = NULL;
 213  223          boolean_t pin_initialized = B_FALSE;
 214  224          uchar_t *tmp_old_pin = NULL, *tmp_new_pin = NULL;
 215  225          CK_RV   rv = CKR_OK;
      226 +        size_t  len = 0;
 216  227  
 217  228          /*
 218  229           * Check to see if keystore is initialized.
 219  230           */
 220  231          rv = soft_keystore_pin_initialized(&pin_initialized, &ks_cryptpin,
 221  232              B_FALSE);
 222  233          if (rv != CKR_OK)
 223  234                  return (rv);
 224  235  
 225  236          /*
↓ open down ↓ 57 lines elided ↑ open up ↑
 283  294                  rv = CKR_FUNCTION_FAILED;
 284  295                  goto cleanup;
 285  296          } else {
 286  297                  (void) pthread_mutex_lock(&soft_giant_mutex);
 287  298                  soft_slot.userpin_change_needed = 0;
 288  299                  (void) pthread_mutex_unlock(&soft_giant_mutex);
 289  300                  rv = CKR_OK;
 290  301          }
 291  302  
 292  303  cleanup:
 293      -        if (salt)
 294      -                free(salt);
 295      -        if (ks_cryptpin)
 296      -                free(ks_cryptpin);
 297      -        if (tmp_old_pin)
 298      -                free(tmp_old_pin);
 299      -        if (tmp_new_pin)
 300      -                free(tmp_new_pin);
      304 +        if (salt) {
      305 +                len = strlen(salt) + 1;
      306 +                freezero(salt, len);
      307 +        }
      308 +        if (ks_cryptpin) {
      309 +                len = strlen(ks_cryptpin) + 1;
      310 +                freezero(ks_cryptpin, len);
      311 +        }
      312 +        if (tmp_old_pin) {
      313 +                len = strlen((char *)tmp_old_pin) + 1;
      314 +                freezero(tmp_old_pin, len);
      315 +        }
      316 +        if (tmp_new_pin) {
      317 +                len = strlen((char *)tmp_new_pin) + 1;
      318 +                freezero(tmp_new_pin, len);
      319 +        }
 301  320  
 302  321          return (rv);
 303  322  }
 304  323  
 305  324  /*
 306  325   * soft_keystore_pack_obj()
 307  326   *
 308  327   * Arguments:
 309  328   *
 310  329   *      obj:    pointer to the soft_object_t of the token object to
↓ open down ↓ 157 lines elided ↑ open up ↑
 468  487                  if (template.ulValueLen > 0) {
 469  488                          template.pValue = malloc(template.ulValueLen);
 470  489                          if (template.pValue == NULL) {
 471  490                                  return (CKR_HOST_MEMORY);
 472  491                          }
 473  492                          (void) memcpy(template.pValue, buf,
 474  493                              template.ulValueLen);
 475  494                  }
 476  495  
 477  496                  rv = soft_add_extra_attr(&template, obj);
 478      -                if (template.pValue) {
 479      -                        free(template.pValue);
 480      -                }
      497 +                freezero(template.pValue, template.ulValueLen);
 481  498  
 482  499                  if (rv != CKR_OK) {
 483  500                          return (rv);
 484  501                  }
 485  502  
 486  503                  buf = buf + ROUNDUP(template.ulValueLen, 8);
 487  504          }
 488  505  
 489  506          /*
 490  507           * Unpack the key itself.
↓ open down ↓ 45 lines elided ↑ open up ↑
 536  553                  return (CKR_HOST_MEMORY);
 537  554          }
 538  555  
 539  556          (void) memcpy(template.pValue, buf, template.ulValueLen);
 540  557          if (cert) {
 541  558                  rv = get_cert_attr_from_template(cert_dest, &template);
 542  559          } else {
 543  560                  rv = get_bigint_attr_from_template(key_dest, &template);
 544  561          }
 545  562  
 546      -        free(template.pValue);
      563 +        freezero(template.pValue, template.ulValueLen);
 547  564          if (rv != CKR_OK) {
 548  565                  return (rv);
 549  566          }
 550  567  
 551  568          *offset = sizeof (uint64_t) + template.ulValueLen;
 552  569          return (CKR_OK);
 553  570  }
 554  571  
 555  572  
 556  573  /*
↓ open down ↓ 1293 lines elided ↑ open up ↑
1850 1867  
1851 1868          uchar_t *buf;
1852 1869          size_t len;
1853 1870          CK_RV rv;
1854 1871  
1855 1872          rv = soft_keystore_pack_obj(objp, &buf, &len);
1856 1873          if (rv != CKR_OK)
1857 1874                  return (rv);
1858 1875  
1859 1876          (void) pthread_mutex_lock(&soft_slot.slot_mutex);
1860      -        if (objp->object_type == TOKEN_PUBLIC) {
1861      -                if ((soft_keystore_put_new_obj(buf, len, B_TRUE,
1862      -                    B_FALSE, &objp->ks_handle)) == -1) {
1863      -                        (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1864      -                        free(buf);
1865      -                        return (CKR_FUNCTION_FAILED);
1866      -                }
1867      -        } else {
1868      -                if ((soft_keystore_put_new_obj(buf, len, B_FALSE,
1869      -                    B_FALSE, &objp->ks_handle)) == -1) {
1870      -                        (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1871      -                        free(buf);
1872      -                        return (CKR_FUNCTION_FAILED);
1873      -                }
     1877 +        if (soft_keystore_put_new_obj(buf, len,
     1878 +            !!(objp->object_type == TOKEN_PUBLIC), B_FALSE,
     1879 +            &objp->ks_handle) == -1) {
     1880 +                rv = CKR_FUNCTION_FAILED;
1874 1881          }
1875 1882          (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
1876      -        free(buf);
1877      -        return (CKR_OK);
1878 1883  
     1884 +        freezero(buf, len);
     1885 +        return (rv);
1879 1886  }
1880 1887  
1881 1888  /*
1882 1889   * Modify the in-core token object and then write it to
1883 1890   * a keystore file.
1884 1891   */
1885 1892  CK_RV
1886 1893  soft_modify_object_to_keystore(soft_object_t *objp)
1887 1894  {
1888 1895  
↓ open down ↓ 1 lines elided ↑ open up ↑
1890 1897          size_t len;
1891 1898          CK_RV rv;
1892 1899  
1893 1900          rv = soft_keystore_pack_obj(objp, &buf, &len);
1894 1901          if (rv != CKR_OK)
1895 1902                  return (rv);
1896 1903  
1897 1904          /* B_TRUE: caller has held a writelock on the keystore */
1898 1905          if (soft_keystore_modify_obj(&objp->ks_handle, buf, len,
1899 1906              B_TRUE) < 0) {
1900      -                return (CKR_FUNCTION_FAILED);
     1907 +                rv = CKR_FUNCTION_FAILED;
1901 1908          }
1902 1909  
1903      -        free(buf);
1904      -        return (CKR_OK);
     1910 +        freezero(buf, len);
     1911 +        return (rv);
1905 1912  
1906 1913  }
1907 1914  
1908 1915  /*
1909 1916   * Read the token object from the keystore file.
1910 1917   */
1911 1918  CK_RV
1912 1919  soft_get_token_objects_from_keystore(ks_search_type_t type)
1913 1920  {
1914 1921          CK_RV rv;
↓ open down ↓ 20 lines elided ↑ open up ↑
1935 1942                                  soft_cleanup_cert_object(new_objp);
1936 1943                          else
1937 1944                                  soft_cleanup_object(new_objp);
1938 1945                          goto cleanup;
1939 1946                  }
1940 1947  
1941 1948                  soft_add_token_object_to_slot(new_objp);
1942 1949  
1943 1950                  /* Free the ks_obj list */
1944 1951                  ks_obj_next = ks_obj->next;
1945      -                if (ks_obj->buf)
1946      -                        free(ks_obj->buf);
     1952 +                freezero(ks_obj->buf, ks_obj->size);
1947 1953                  free(ks_obj);
1948 1954                  ks_obj = ks_obj_next;
1949 1955          }
1950 1956  
1951 1957          return (CKR_OK);
1952 1958  
1953 1959  cleanup:
1954 1960          while (ks_obj) {
1955 1961                  ks_obj_next = ks_obj->next;
1956      -                free(ks_obj->buf);
     1962 +                freezero(ks_obj->buf, ks_obj->size);
1957 1963                  free(ks_obj);
1958 1964                  ks_obj = ks_obj_next;
1959 1965          }
1960 1966          return (rv);
1961 1967  }
1962 1968  
1963 1969  /*
1964 1970   * soft_gen_crypt_key()
1965 1971   *
1966 1972   * Arguments:
↓ open down ↓ 330 lines elided ↑ open up ↑
2297 2303  
2298 2304                  /* Copy Initialization Vector (IV) into the context. */
2299 2305                  (void) memcpy(soft_aes_ctx->ivec, ivec, AES_BLOCK_LEN);
2300 2306  
2301 2307                  /* Allocate a context for AES cipher-block chaining. */
2302 2308                  soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2303 2309                      soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2304 2310                      soft_aes_ctx->ivec);
2305 2311  
2306 2312                  if (soft_aes_ctx->aes_cbc == NULL) {
2307      -                        bzero(soft_aes_ctx->key_sched,
     2313 +                        freezero(soft_aes_ctx->key_sched,
2308 2314                              soft_aes_ctx->keysched_len);
2309      -                        free(soft_aes_ctx->key_sched);
2310 2315                          if (encrypt) {
2311 2316                                  free(token_session.encrypt.context);
2312 2317                                  token_session.encrypt.context = NULL;
2313 2318                          } else {
2314 2319                                  free(token_session.encrypt.context);
2315 2320                                  token_session.encrypt.context = NULL;
2316 2321                          }
2317 2322  
2318 2323                          (void) pthread_mutex_unlock(&token_session.
2319 2324                              session_mutex);
↓ open down ↓ 77 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX