/
niceSOFT
/
libxcrypt
Обзор
Документация
Войти
/
niceSOFT
/
libxcrypt
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
lib/crypt-sm3-yescrypt.c
189 строк
6 KB
Stanislav Zidek
fix -Werror=discarded-qualifiers
10 дек 2025, 16:10
10 дек 2025, 16:10
174c24d
Код
Авторство
О чём код?
/* Copyright (C) 2024 Björn Esser besser82@fedoraproject.org * * Redistribution and use in source and binary forms, with or without * modification, are permitted. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "crypt-port.h" #if INCLUDE_sm3_yescrypt #define YESCRYPT_INTERNAL #include "alg-yescrypt.h" #undef YESCRYPT_INTERNAL #include "alg-sm3-hmac.h" #include <errno.h> /* upper level hmac for tests */ #ifndef outer_sm3_hmac #define outer_sm3_hmac sm3_hmac #endif /* For use in scratch space by crypt_gost_yescrypt_rn(). */ typedef struct { sm3_hmac_ctx_t sm3buf; yescrypt_local_t local; uint8_t outbuf[CRYPT_OUTPUT_SIZE], sm3setting[CRYPT_OUTPUT_SIZE], hk[32], interm[32], y[32], *retval; } crypt_sm3_yescrypt_internal_t; static_assert (sizeof (crypt_sm3_yescrypt_internal_t) <= ALG_SPECIFIC_SIZE, "ALG_SPECIFIC_SIZE is too small for SM3-YESCRYPT."); /* * As OUTPUT is initialized with a failure token before gensalt_yescrypt_rn * is called, in case of an error we could just set an appropriate errno * and return. */ void gensalt_sm3_yescrypt_rn (unsigned long count, const uint8_t *rbytes, size_t nrbytes, uint8_t *output, size_t o_size) { /* Up to 512 bits (64 bytes) of entropy for computing the salt portion of the MCF-setting are supported. */ nrbytes = (nrbytes > 64 ? 64 : nrbytes); if (o_size < 6 + 8 * 6 + BASE64_LEN (nrbytes) + 1 || CRYPT_GENSALT_OUTPUT_SIZE < 6 + 8 * 6 + BASE64_LEN (nrbytes) + 1) { errno = ERANGE; return; } /* We pass 'o_size - 3' to gensalt, because we need to shift the prefix by 3 chars to insert the sm3 marker. */ gensalt_yescrypt_rn (count, rbytes, nrbytes, output, o_size - 3); /* Check for failures. */ if (output[0] == '*') return; /* Shift output three bytes further. */ memmove (output + 3, output, strlen ((const char *) output) + 1); /* Insert the sm3 marker. */ output[1] = 's'; output[2] = 'm'; output[3] = '3'; } void crypt_sm3_yescrypt_rn (const char *phrase, size_t phr_size, const char *setting, size_t set_size, uint8_t *output, size_t o_size, void *scratch, size_t s_size) { if (o_size < set_size + 1 + 43 + 1 || CRYPT_OUTPUT_SIZE < set_size + 1 + 43 + 1 || s_size < sizeof (crypt_sm3_yescrypt_internal_t)) { errno = ERANGE; return; } /* Fail when called with wrong prefix. */ if (strncmp (setting, "$sm3y$", 6)) { errno = EINVAL; return; } crypt_sm3_yescrypt_internal_t *intbuf = scratch; if (yescrypt_init_local (&intbuf->local)) return; /* convert gost setting to yescrypt setting */ intbuf->sm3setting[0] = '$'; intbuf->sm3setting[1] = 'y'; intbuf->sm3setting[2] = '$'; strcpy_or_abort (&intbuf->sm3setting[3], set_size - 3, setting + 6); intbuf->retval = yescrypt_r (NULL, &intbuf->local, (const uint8_t *) phrase, phr_size, intbuf->sm3setting, NULL, intbuf->outbuf + 3, o_size - 3); if (!intbuf->retval) errno = EINVAL; if (yescrypt_free_local (&intbuf->local) || !intbuf->retval) return; intbuf->outbuf[0] = '$'; intbuf->outbuf[1] = 's'; intbuf->outbuf[2] = 'm'; intbuf->outbuf[3] = '3'; /* extract yescrypt output from "$y$param$salt$output" */ char *hptr = strchr ((char *) intbuf->retval + 3, '$'); if (!hptr) { errno = EINVAL; return; } hptr = strchr (hptr + 1, '$'); if (!hptr) { errno = EINVAL; return; } hptr++; /* start of output */ /* decode yescrypt output into its raw 256-bit form */ size_t ylen = sizeof (intbuf->y); if (!decode64 (intbuf->y, &ylen, (uint8_t *) hptr, strlen (hptr)) || ylen != sizeof (intbuf->y)) { errno = EINVAL; return; } /* * SM3_HMAC( * SM3_HMAC(SM3(K), S), * yescrypt(K, S) * ) * yescrypt output is used in place of message, * thus, its crypto properties are superseded by SM3. * Password is always hashed for inner hmac to avoid * collisions between hashed and unhashed passwords. */ sm3_hash ((const uint8_t *) phrase, phr_size, intbuf->hk, &intbuf->sm3buf.sm3_ctx); sm3_hmac (intbuf->hk, sizeof (intbuf->hk), (const uint8_t *) setting, (size_t) ((uint8_t *) hptr - intbuf->retval), intbuf->interm, &intbuf->sm3buf); outer_sm3_hmac (intbuf->interm, sizeof (intbuf->interm), intbuf->y, sizeof (intbuf->y), intbuf->y, &intbuf->sm3buf); encode64 ((uint8_t *) hptr, o_size - (size_t) ((uint8_t *) hptr - intbuf->retval), intbuf->y, sizeof (intbuf->y)); strcpy_or_abort (output, o_size, intbuf->outbuf); return; } #endif /* INCLUDE_sm3_yescrypt */