LCOV - code coverage report
Current view: top level - lib/util - uuid.c (source / functions) Hit Total Coverage
Test: ut_cov_unit.info Lines: 23 24 95.8 %
Date: 2024-12-13 04:02:48 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*   SPDX-License-Identifier: BSD-3-Clause
       2             :  *   Copyright (C) 2018 Intel Corporation.
       3             :  *   All rights reserved.
       4             :  */
       5             : 
       6             : #include "spdk/uuid.h"
       7             : #include "spdk/config.h"
       8             : #include "spdk/log.h"
       9             : 
      10             : #ifndef SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1
      11             : #include <openssl/evp.h>
      12             : #endif /* SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1 */
      13             : 
      14             : #ifndef __FreeBSD__
      15             : 
      16             : #include <uuid/uuid.h>
      17             : 
      18             : SPDK_STATIC_ASSERT(sizeof(struct spdk_uuid) == sizeof(uuid_t), "Size mismatch");
      19             : 
      20             : int
      21         102 : spdk_uuid_parse(struct spdk_uuid *uuid, const char *uuid_str)
      22             : {
      23         102 :         return uuid_parse(uuid_str, (void *)uuid) == 0 ? 0 : -EINVAL;
      24             : }
      25             : 
      26             : int
      27         565 : spdk_uuid_fmt_lower(char *uuid_str, size_t uuid_str_size, const struct spdk_uuid *uuid)
      28             : {
      29         565 :         if (uuid_str_size < SPDK_UUID_STRING_LEN) {
      30           0 :                 return -EINVAL;
      31             :         }
      32             : 
      33         565 :         uuid_unparse_lower((void *)uuid, uuid_str);
      34         565 :         return 0;
      35         565 : }
      36             : 
      37             : int
      38        8993 : spdk_uuid_compare(const struct spdk_uuid *u1, const struct spdk_uuid *u2)
      39             : {
      40        8993 :         return uuid_compare((void *)u1, (void *)u2);
      41             : }
      42             : 
      43             : void
      44         846 : spdk_uuid_generate(struct spdk_uuid *uuid)
      45             : {
      46         846 :         uuid_generate((void *)uuid);
      47         846 : }
      48             : 
      49             : void
      50         611 : spdk_uuid_copy(struct spdk_uuid *dst, const struct spdk_uuid *src)
      51             : {
      52         611 :         uuid_copy((void *)dst, (void *)src);
      53         611 : }
      54             : 
      55             : bool
      56        1709 : spdk_uuid_is_null(const struct spdk_uuid *uuid)
      57             : {
      58        1709 :         return uuid_is_null((void *)uuid);
      59             : }
      60             : 
      61             : void
      62         476 : spdk_uuid_set_null(struct spdk_uuid *uuid)
      63             : {
      64         476 :         uuid_clear((void *)uuid);
      65         476 : }
      66             : 
      67             : #else
      68             : 
      69             : #include <uuid.h>
      70             : 
      71             : SPDK_STATIC_ASSERT(sizeof(struct spdk_uuid) == sizeof(uuid_t), "Size mismatch");
      72             : 
      73             : int
      74             : spdk_uuid_parse(struct spdk_uuid *uuid, const char *uuid_str)
      75             : {
      76             :         uint32_t status;
      77             : 
      78             :         /* uuid_from_string() differs from uuid_parse() in the way it handles empty strings: the
      79             :          * former succeeds and returns a NULL UUID, while the latter treats is an error and returns
      80             :          * non-zero exit code.  So, to keep the behavior consistent between Linux and FreeBSD, we
      81             :          * explicitly check for an empty string here.
      82             :          */
      83             :         if (strlen(uuid_str) == 0) {
      84             :                 return -EINVAL;
      85             :         }
      86             : 
      87             :         uuid_from_string(uuid_str, (uuid_t *)uuid, &status);
      88             : 
      89             :         return status == 0 ? 0 : -EINVAL;
      90             : }
      91             : 
      92             : int
      93             : spdk_uuid_fmt_lower(char *uuid_str, size_t uuid_str_size, const struct spdk_uuid *uuid)
      94             : {
      95             :         uint32_t status;
      96             :         char *str;
      97             : 
      98             :         if (uuid_str_size < SPDK_UUID_STRING_LEN) {
      99             :                 return -EINVAL;
     100             :         }
     101             : 
     102             :         uuid_to_string((const uuid_t *)uuid, &str, &status);
     103             : 
     104             :         if (status == uuid_s_no_memory) {
     105             :                 return -ENOMEM;
     106             :         }
     107             : 
     108             :         snprintf(uuid_str, uuid_str_size, "%s", str);
     109             :         free(str);
     110             : 
     111             :         return 0;
     112             : }
     113             : 
     114             : int
     115             : spdk_uuid_compare(const struct spdk_uuid *u1, const struct spdk_uuid *u2)
     116             : {
     117             :         return uuid_compare((const uuid_t *)u1, (const uuid_t *)u2, NULL);
     118             : }
     119             : 
     120             : void
     121             : spdk_uuid_generate(struct spdk_uuid *uuid)
     122             : {
     123             :         uuid_create((uuid_t *)uuid, NULL);
     124             : }
     125             : 
     126             : void
     127             : spdk_uuid_copy(struct spdk_uuid *dst, const struct spdk_uuid *src)
     128             : {
     129             :         memcpy(dst, src, sizeof(*dst));
     130             : }
     131             : 
     132             : bool
     133             : spdk_uuid_is_null(const struct spdk_uuid *uuid)
     134             : {
     135             :         return uuid_is_nil((const uuid_t *)uuid, NULL);
     136             : }
     137             : 
     138             : void
     139             : spdk_uuid_set_null(struct spdk_uuid *uuid)
     140             : {
     141             :         uuid_create_nil((uuid_t *)uuid, NULL);
     142             : }
     143             : 
     144             : #endif
     145             : 
     146             : int
     147          22 : spdk_uuid_generate_sha1(struct spdk_uuid *uuid, struct spdk_uuid *ns_uuid, const char *name,
     148             :                         size_t len)
     149             : {
     150             : #ifdef SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1
     151          22 :         uuid_generate_sha1((void *)uuid, (void *)ns_uuid, name, len);
     152          22 :         return 0;
     153             : #else
     154             :         EVP_MD_CTX *mdctx;
     155             :         const EVP_MD *md;
     156             :         unsigned char md_value[EVP_MAX_MD_SIZE];
     157             :         unsigned int md_len;
     158             : 
     159             :         md = EVP_sha1();
     160             :         assert(md != NULL);
     161             : 
     162             :         mdctx = EVP_MD_CTX_new();
     163             :         if (mdctx == NULL) {
     164             :                 return -ENOMEM;
     165             :         }
     166             : 
     167             :         if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
     168             :                 SPDK_ERRLOG("Could not initialize EVP digest!\n");
     169             :                 goto err;
     170             :         }
     171             :         if (EVP_DigestUpdate(mdctx, ns_uuid, sizeof(struct spdk_uuid)) != 1) {
     172             :                 SPDK_ERRLOG("Could update EVP digest with namespace UUID!\n");
     173             :                 goto err;
     174             :         }
     175             :         if (EVP_DigestUpdate(mdctx, name, len) != 1) {
     176             :                 SPDK_ERRLOG("Could update EVP digest with assigned name!\n");
     177             :                 goto err;
     178             :         }
     179             :         if (EVP_DigestFinal_ex(mdctx, md_value, &md_len) != 1) {
     180             :                 SPDK_ERRLOG("Could not generate EVP digest!\n");
     181             :                 goto err;
     182             :         }
     183             :         EVP_MD_CTX_free(mdctx);
     184             : 
     185             :         memcpy(uuid, md_value, 16);
     186             :         /* This part mimics original uuid_generate_sha1() from libuuid/src/gen_uuid.c.
     187             :          * The original uuid structure included from uuid.h looks like this:
     188             :          * struct uuid {
     189             :          *      uint32_t        time_low;
     190             :          *      uint16_t        time_mid;
     191             :          *      uint16_t        time_hi_and_version;
     192             :          *      uint16_t        clock_seq;
     193             :          *      uint8_t         node[6];
     194             :          * };
     195             :          * so uuid->u.raw[6] and uuid->u.raw[8] are time_hi_and_version and clock_seq respectively.
     196             :          */
     197             :         uuid->u.raw[6] = (uuid->u.raw[6] & 0x0f) | 0x50;
     198             :         uuid->u.raw[8] = (uuid->u.raw[8] & 0x3f) | 0x80;
     199             : 
     200             :         return 0;
     201             : 
     202             : err:
     203             :         EVP_MD_CTX_free(mdctx);
     204             :         return -EINVAL;
     205             : 
     206             : #endif /* SPDK_CONFIG_HAVE_UUID_GENERATE_SHA1 */
     207             : }

Generated by: LCOV version 1.15