Print this page
6414175 kcf.conf's supportedlist not providing much usefulness

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c
          +++ new/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_ioctl.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5      - * Common Development and Distribution License, Version 1.0 only
   6      - * (the "License").  You may not use this file except in compliance
   7      - * with the License.
        5 + * Common Development and Distribution License (the "License").
        6 + * You may not use this file except in compliance with the License.
   8    7   *
   9    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10    9   * or http://www.opensolaris.org/os/licensing.
  11   10   * See the License for the specific language governing permissions
  12   11   * and limitations under the License.
  13   12   *
  14   13   * When distributing Covered Code, include this CDDL HEADER in each
  15   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   15   * If applicable, add the following below this CDDL HEADER, with the
  17   16   * fields enclosed by brackets "[]" replaced with your own identifying
  18   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   18   *
  20   19   * CDDL HEADER END
  21   20   */
  22   21  /*
  23      - * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
       22 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   23   * Use is subject to license terms.
  25   24   */
  26   25  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   26  #include <fcntl.h>
  30   27  #include <stdio.h>
  31   28  #include <stdlib.h>
  32   29  #include <strings.h>
  33   30  #include <unistd.h>
  34   31  #include <locale.h>
  35   32  #include <libgen.h>
  36   33  #include <sys/types.h>
  37   34  #include <zone.h>
  38   35  #include <sys/crypto/ioctladmin.h>
↓ open down ↓ 6 lines elided ↑ open up ↑
  45   42  
  46   43  /*
  47   44   * Prepare the argument for the LOAD_SOFT_CONFIG ioctl call for the
  48   45   * provider pointed by pent.  Return NULL if out of memory.
  49   46   */
  50   47  crypto_load_soft_config_t *
  51   48  setup_soft_conf(entry_t *pent)
  52   49  {
  53   50          crypto_load_soft_config_t       *pload_soft_conf;
  54   51          mechlist_t      *plist;
  55      -        uint_t  sup_count;
  56      -        size_t  extra_mech_size = 0;
  57      -        int     i;
       52 +        uint_t          sup_count;
       53 +        size_t          extra_mech_size = 0;
       54 +        int             i;
  58   55  
  59   56          if (pent == NULL) {
  60   57                  return (NULL);
  61   58          }
  62   59  
  63   60          sup_count = pent->sup_count;
  64   61          if (sup_count > 1) {
  65   62                  extra_mech_size = sizeof (crypto_mech_name_t) *
  66   63                      (sup_count - 1);
  67   64          }
↓ open down ↓ 20 lines elided ↑ open up ↑
  88   85  }
  89   86  
  90   87  
  91   88  /*
  92   89   * Prepare the argument for the LOAD_SOFT_DISABLED ioctl call for the
  93   90   * provider pointed by pent.  Return NULL if out of memory.
  94   91   */
  95   92  crypto_load_soft_disabled_t *
  96   93  setup_soft_dis(entry_t *pent)
  97   94  {
  98      -        crypto_load_soft_disabled_t     *pload_soft_dis;
  99      -        mechlist_t      *plist;
 100      -        size_t  extra_mech_size = 0;
 101      -        uint_t  dis_count;
 102      -        int     i;
       95 +        crypto_load_soft_disabled_t     *pload_soft_dis = NULL;
       96 +        mechlist_t      *plist = NULL;
       97 +        size_t          extra_mech_size = 0;
       98 +        uint_t          dis_count;
       99 +        int             i;
 103  100  
 104  101          if (pent == NULL) {
 105  102                  return (NULL);
 106  103          }
 107  104  
 108  105          dis_count = pent->dis_count;
 109  106          if (dis_count > 1) {
 110  107                  extra_mech_size = sizeof (crypto_mech_name_t) *
 111  108                      (dis_count - 1);
 112  109          }
↓ open down ↓ 20 lines elided ↑ open up ↑
 133  130  }
 134  131  
 135  132  
 136  133  /*
 137  134   * Prepare the argument for the LOAD_DEV_DISABLED ioctl call for the
 138  135   * provider pointed by pent.  Return NULL if out of memory.
 139  136   */
 140  137  crypto_load_dev_disabled_t *
 141  138  setup_dev_dis(entry_t *pent)
 142  139  {
 143      -        crypto_load_dev_disabled_t      *pload_dev_dis;
 144      -        mechlist_t      *plist;
 145      -        size_t  extra_mech_size = 0;
 146      -        uint_t  dis_count;
 147      -        int     i;
 148      -        char    pname[MAXNAMELEN];
 149      -        int     inst_num;
      140 +        crypto_load_dev_disabled_t      *pload_dev_dis = NULL;
      141 +        mechlist_t      *plist = NULL;
      142 +        size_t          extra_mech_size = 0;
      143 +        uint_t          dis_count;
      144 +        int             i;
      145 +        char            pname[MAXNAMELEN];
      146 +        int             inst_num;
 150  147  
 151  148          if (pent == NULL) {
 152  149                  return (NULL);
 153  150          }
 154  151  
 155  152          /* get the device name and the instance number */
 156  153          if (split_hw_provname(pent->name, pname, &inst_num) == FAILURE) {
 157  154                  return (NULL);
 158  155          }
 159  156  
↓ open down ↓ 49 lines elided ↑ open up ↑
 209  206  
 210  207          (void) strlcpy(punload_soft->sm_name, pent->name, MAXNAMELEN);
 211  208  
 212  209          return (punload_soft);
 213  210  }
 214  211  
 215  212  
 216  213  /*
 217  214   * Prepare the calling argument for the GET_SOFT_INFO call for the provider
 218  215   * with the number of mechanisms specified in the second argument.
      216 + *
      217 + * Called by get_soft_info().
 219  218   */
 220  219  static crypto_get_soft_info_t *
 221  220  setup_get_soft_info(char *provname, int count)
 222  221  {
 223      -        crypto_get_soft_info_t *psoft_info;
 224      -        size_t extra_mech_size = 0;
      222 +        crypto_get_soft_info_t  *psoft_info;
      223 +        size_t                  extra_mech_size = 0;
 225  224  
 226  225          if (provname == NULL) {
 227  226                  return (NULL);
 228  227          }
 229  228  
 230  229          if (count > 1) {
 231  230                  extra_mech_size = sizeof (crypto_mech_name_t) * (count - 1);
 232  231          }
 233  232  
 234  233          psoft_info = malloc(sizeof (crypto_get_soft_info_t) + extra_mech_size);
↓ open down ↓ 8 lines elided ↑ open up ↑
 243  242          return (psoft_info);
 244  243  }
 245  244  
 246  245  
 247  246  /*
 248  247   * Get the device list from kernel.
 249  248   */
 250  249  int
 251  250  get_dev_list(crypto_get_dev_list_t **ppdevlist)
 252  251  {
 253      -        crypto_get_dev_list_t *pdevlist;
 254      -        int fd;
 255      -        int count = DEFAULT_DEV_NUM;
      252 +        crypto_get_dev_list_t   *pdevlist;
      253 +        int                     fd = -1;
      254 +        int                     count = DEFAULT_DEV_NUM;
 256  255  
 257  256          pdevlist = malloc(sizeof (crypto_get_dev_list_t) +
 258  257              sizeof (crypto_dev_list_entry_t) * (count - 1));
 259  258          if (pdevlist == NULL) {
 260  259                  cryptodebug("out of memory.");
 261  260                  return (FAILURE);
 262  261          }
 263  262  
 264  263          if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
 265  264                  cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
↓ open down ↓ 45 lines elided ↑ open up ↑
 311  310  }
 312  311  
 313  312  
 314  313  /*
 315  314   * Get all the mechanisms supported by the hardware provider.
 316  315   * The result will be stored in the second argument.
 317  316   */
 318  317  int
 319  318  get_dev_info(char *devname, int inst_num, int count, mechlist_t **ppmechlist)
 320  319  {
 321      -        crypto_get_dev_info_t *dev_info;
 322      -        mechlist_t *phead;
 323      -        mechlist_t *pcur;
 324      -        mechlist_t *pmech;
 325      -        int fd;
 326      -        int i;
 327      -        int rc;
      320 +        crypto_get_dev_info_t   *dev_info;
      321 +        mechlist_t      *phead;
      322 +        mechlist_t      *pcur;
      323 +        mechlist_t      *pmech;
      324 +        int             fd = -1;
      325 +        int             i;
      326 +        int             rc;
 328  327  
 329  328          if (devname == NULL || count < 1) {
 330  329                  cryptodebug("get_dev_info(): devname is NULL or bogus count");
 331  330                  return (FAILURE);
 332  331          }
 333  332  
 334  333          /* Set up the argument for the CRYPTO_GET_DEV_INFO ioctl call */
 335  334          dev_info = malloc(sizeof (crypto_get_dev_info_t) +
 336  335              sizeof (crypto_mech_name_t) * (count - 1));
 337  336          if (dev_info == NULL) {
↓ open down ↓ 50 lines elided ↑ open up ↑
 388  387          } else {
 389  388                  free_mechlist(phead);
 390  389          }
 391  390  
 392  391          free(dev_info);
 393  392          (void) close(fd);
 394  393          return (rc);
 395  394  }
 396  395  
 397  396  
 398      -
 399  397  /*
 400  398   * Get the supported mechanism list of the software provider from kernel.
      399 + *
      400 + * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
      401 + * If NULL, this function calls get_kcfconf_info() internally.
 401  402   */
 402  403  int
 403      -get_soft_info(char *provname, mechlist_t **ppmechlist)
      404 +get_soft_info(char *provname, mechlist_t **ppmechlist,
      405 +        entrylist_t *phardlist, entrylist_t *psoftlist)
 404  406  {
      407 +        boolean_t               in_kernel = B_FALSE;
 405  408          crypto_get_soft_info_t  *psoft_info;
 406      -        mechlist_t      *phead;
 407      -        mechlist_t      *pmech;
 408      -        mechlist_t      *pcur;
 409      -        entry_t *pent;
 410      -        int     count;
 411      -        int     fd;
 412      -        int     rc;
 413      -        int     i;
      409 +        mechlist_t              *phead;
      410 +        mechlist_t              *pmech;
      411 +        mechlist_t              *pcur;
      412 +        entry_t                 *pent = NULL;
      413 +        int                     count;
      414 +        int                     fd = -1;
      415 +        int                     rc;
      416 +        int                     i;
 414  417  
 415  418          if (provname == NULL) {
 416  419                  return (FAILURE);
 417  420          }
 418  421  
 419  422          if (getzoneid() == GLOBAL_ZONEID) {
 420  423                  /* use kcf.conf for kernel software providers in global zone */
 421      -                if ((pent = getent_kef(provname)) == NULL) {
 422      -                        cryptoerror(LOG_STDERR, gettext("%s does not exist."),
 423      -                            provname);
 424      -                        return (FAILURE);
      424 +                if ((pent = getent_kef(provname, phardlist, psoftlist)) ==
      425 +                    NULL) {
      426 +
      427 +                        /* No kcf.conf entry for this provider */
      428 +                        if (check_kernel_for_soft(provname, NULL, &in_kernel)
      429 +                            == FAILURE) {
      430 +                                return (FAILURE);
      431 +                        } else if (in_kernel == B_FALSE) {
      432 +                                cryptoerror(LOG_STDERR,
      433 +                                    gettext("%s does not exist."), provname);
      434 +                                return (FAILURE);
      435 +                        }
      436 +
      437 +                        /*
      438 +                         * Set mech count to 1.  It will be reset to the
      439 +                         * correct value later if the setup buffer is too small.
      440 +                         */
      441 +                        count = 1;
      442 +                } else {
      443 +                        count = pent->sup_count;
      444 +                        free_entry(pent);
 425  445                  }
 426      -                count = pent->sup_count;
 427      -                free_entry(pent);
 428  446          } else {
 429  447                  /*
 430      -                 * kcf.conf not there in non-global zone, set mech count to 1;
 431      -                 * it will be reset to the correct value later if the setup
 432      -                 * buffer is too small
      448 +                 * kcf.conf not there in non-global zone: set mech count to 1.
      449 +                 * It will be reset to the correct value later if the setup
      450 +                 * buffer is too small.
 433  451                   */
 434  452                  count = 1;
 435  453          }
 436  454  
 437  455          if ((psoft_info = setup_get_soft_info(provname, count)) == NULL) {
 438  456                  return (FAILURE);
 439  457          }
 440  458  
 441  459          if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
 442  460                  cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
↓ open down ↓ 33 lines elided ↑ open up ↑
 476  494  
 477  495          (void) close(fd);
 478  496          if (psoft_info->si_return_value != CRYPTO_SUCCESS) {
 479  497                  cryptodebug("CRYPTO_GET_SOFT_INFO ioctl failed, "
 480  498                      "return_value = %d", psoft_info->si_return_value);
 481  499                  free(psoft_info);
 482  500                  return (FAILURE);
 483  501          }
 484  502  
 485  503  
 486      -        /* Get the mechanism list and return it */
      504 +        /* Build the mechanism linked list and return it */
 487  505          rc = SUCCESS;
 488  506          phead = pcur = NULL;
 489  507          for (i = 0; i < psoft_info->si_count; i++) {
 490  508                  pmech = create_mech(&psoft_info->si_list[i][0]);
 491  509                  if (pmech == NULL) {
 492  510                          rc = FAILURE;
 493  511                          break;
 494  512                  } else {
 495  513                          if (phead == NULL) {
 496  514                                  phead = pcur = pmech;
↓ open down ↓ 15 lines elided ↑ open up ↑
 512  530  }
 513  531  
 514  532  
 515  533  /*
 516  534   * Get the kernel software provider list from kernel.
 517  535   */
 518  536  int
 519  537  get_soft_list(crypto_get_soft_list_t **ppsoftlist)
 520  538  {
 521  539          crypto_get_soft_list_t *psoftlist = NULL;
 522      -        int count = DEFAULT_SOFT_NUM;
 523      -        int len;
 524      -        int fd;
      540 +        int     count = DEFAULT_SOFT_NUM;
      541 +        int     len;
      542 +        int     fd = -1;
 525  543  
 526  544          if ((fd = open(ADMIN_IOCTL_DEVICE, O_RDONLY)) == -1) {
 527  545                  cryptoerror(LOG_STDERR, gettext("failed to open %s: %s"),
 528  546                      ADMIN_IOCTL_DEVICE, strerror(errno));
 529  547                  return (FAILURE);
 530  548          }
 531  549  
 532  550          len = MAXNAMELEN * count;
 533  551          psoftlist = malloc(sizeof (crypto_get_soft_list_t) + len);
 534  552          if (psoftlist == NULL) {
↓ open down ↓ 55 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX