Skip to content

Commit 1d25217

Browse files
ElenaTyulenevasmuellerDD
authored andcommitted
LMS algorithm was added + small change connected with removing the usage of the deprecated API (#1)
* LMS algorithm was added * Removed usage of the deprecated API * Changed compilation lines due to specific OpenSSL layout on Windows + Corrected cryptomb backendns because FIPS CAVP vectors representation was changed Signed-off-by: Stephan Mueller <smueller@chronox.de>
1 parent b2c0c4e commit 1d25217

6 files changed

Lines changed: 230 additions & 15 deletions

File tree

backends.mk

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,14 @@ ifeq (ippcrypto,$(firstword $(MAKECMDGOALS)))
302302
ifeq ($(uname -m),x86_64)
303303
CFLAGS += -mavx2 -mbmi2 -mpopcnt -g
304304
endif
305-
CFLAGS += -Wno-uninitialized
305+
CFLAGS += -Wno-uninitialized -DIPPCP_PREVIEW_LMS
306306

307307
# Static link for lnx
308308
ifeq ($(UNAME_S),Linux)
309309
LDFLAGS += $(IPPCRYPTOROOT)/lib/libippcp.a
310310
LIBRARIES += crypto ssl
311311
else
312-
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/
312+
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/ -L $(OPENSSL_ROOT_DIR)/lib/
313313
LIBRARIES += crypto ssl ippcp
314314
endif
315315
LDFLAGS += -L $(OPENSSL_ROOT_DIR)/lib64/
@@ -333,7 +333,7 @@ ifeq (cryptomb,$(firstword $(MAKECMDGOALS)))
333333
LDFLAGS += $(IPPCRYPTOROOT)/lib/libcrypto_mb.a $(IPPCRYPTOROOT)/lib/libippcp.a
334334
LIBRARIES += crypto ssl
335335
else
336-
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/
336+
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/ -L $(OPENSSL_ROOT_DIR)/lib/
337337
LIBRARIES += crypto ssl ippcp crypto_mb
338338
endif
339339

@@ -357,11 +357,11 @@ ifeq (cryptombssl,$(firstword $(MAKECMDGOALS)))
357357
LDFLAGS += $(IPPCRYPTOROOT)/lib/libcrypto_mb.a $(IPPCRYPTOROOT)/lib/libippcp.a
358358
LIBRARIES += crypto ssl
359359
else
360-
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/
360+
LDFLAGS += -L $(IPPCRYPTOROOT)/lib/ -L $(OPENSSL_ROOT_DIR)/lib/
361361
LIBRARIES += crypto ssl ippcp crypto_mb
362362
endif
363363

364-
LDFLAGS += -L $(OPENSSL_ROOT_DIR)/lib/ -L $(OPENSSL_ROOT_DIR)/bin/
364+
LDFLAGS += -L $(OPENSSL_ROOT_DIR)/lib64/ -L $(OPENSSL_ROOT_DIR)/bin/
365365
LD_LIBRARY_PATH += $(OPENSSL_ROOT_DIR)/lib64/
366366
endif
367367

backends/backend_cryptomb.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,20 +336,26 @@ static int cryptomb_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t parsed_
336336
(void)parsed_flags;
337337
int ret = 0;
338338

339+
IppStatus ipp_sts = ippStsNoErr;
340+
IppsHashMethod* method = NULL;
341+
339342
/* "Feature" of p521 curve - pad the message with leading zeros to 528 bits */
340343
int offset = 0;
341344
ec_type ec = ec_unset;
342345
switch (data->cipher & ACVP_CURVEMASK) {
343346
case ACVP_NISTP256:
344347
ec = nistp256;
348+
method = (IppsHashMethod*)ippsHashMethod_SHA256();
345349
break;
346350
case ACVP_NISTP384:
347351
ec = nistp384;
348-
break;
352+
method = (IppsHashMethod*)ippsHashMethod_SHA384();
353+
break;
349354
case ACVP_NISTP521:
350355
ec = nistp521;
351356
offset = 2;
352-
break;
357+
method = (IppsHashMethod*)ippsHashMethod_SHA512();
358+
break;
353359
default:
354360
logger(LOGGER_ERR, "Unknown curve\n");
355361
}
@@ -369,7 +375,10 @@ static int cryptomb_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t parsed_
369375
for(int i = 0; i < MBX_NUM_BUFFERS; i++) {
370376
memcpy(data_sig_s[i], data->S.buf,data->S.len);
371377
memcpy(data_sig_r[i], data->R.buf,data->R.len);
372-
memcpy(data_msg_digest[i]+offset, data->msg.buf, data->msg.len);
378+
379+
// Use single-buffer to prepare the hash of the raw messages passed from FIPS Lab
380+
ipp_sts = ippsHashMessage_rmf(data->msg.buf, data->msg.len, data_msg_digest[i]+offset, method);
381+
CKNULL_LOG((ipp_sts == ippStsNoErr), ipp_sts, "Error in ippsHashMessage_rmf")
373382

374383
memcpy(data_pub_x_init[i], data->Qx.buf,data->Qx.len);
375384
reverse_bytes((int8u*)data_pub_x[i], (int8u*)data_pub_x_init[i], data->Qx.len);
@@ -405,6 +414,7 @@ static int cryptomb_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t parsed_
405414
data->sigver_success = 0;
406415
}
407416

417+
out:
408418
return ret;
409419
}
410420

backends/backend_cryptomb_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ __attribute__((aligned(64))) static const int8u pSeed[] = "\x00\x00\x00\x00\x00
379379
"\x00\x00";
380380

381381
/* XOR block */
382-
__INLINE void XorBlock(const void* pSrc1, const void* pSrc2, void* pDst, int len)
382+
static void XorBlock(const void* pSrc1, const void* pSrc2, void* pDst, int len)
383383
{
384384
const Ipp8u* p1 = (const Ipp8u*)pSrc1;
385385
const Ipp8u* p2 = (const Ipp8u*)pSrc2;

backends/backend_cryptombssl.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,19 +280,25 @@ static int cryptomb_ssl_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t par
280280
(void)parsed_flags;
281281
int ret = 0;
282282

283+
IppStatus ipp_sts = ippStsNoErr;
284+
IppsHashMethod* method = NULL;
285+
283286
/* "Feature" of p521 curve - padd the message with leading zeros to 528 bits */
284287
int offset = 0;
285288
ec_type ec = ec_unset;
286289
switch (data->cipher & ACVP_CURVEMASK) {
287290
case ACVP_NISTP256:
288291
ec = nistp256;
292+
method = (IppsHashMethod*)ippsHashMethod_SHA256();
289293
break;
290294
case ACVP_NISTP384:
291295
ec = nistp384;
296+
method = (IppsHashMethod*)ippsHashMethod_SHA384();
292297
break;
293298
case ACVP_NISTP521:
294299
ec = nistp521;
295300
offset = 2;
301+
method = (IppsHashMethod*)ippsHashMethod_SHA512();
296302
break;
297303
default:
298304
logger(LOGGER_ERR, "Unknown curve\n");
@@ -313,7 +319,9 @@ static int cryptomb_ssl_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t par
313319
BN_bin2bn(data->S.buf, data->S.len, BN_s);
314320
ECDSA_SIG_set0(pabn_sign[i], BN_r, BN_s);
315321

316-
memcpy(data_msg_digest[i]+offset, data->msg.buf, data->msg.len);
322+
// Use single-buffer to prepare the hash of the raw messages passed from FIPS Lab
323+
ipp_sts = ippsHashMessage_rmf(data->msg.buf, data->msg.len, data_msg_digest[i]+offset, method);
324+
CKNULL_LOG((ipp_sts == ippStsNoErr), ipp_sts, "Error in ippsHashMessage_rmf")
317325

318326
pabn_pubX[i] = BN_new();
319327
BN_bin2bn(data->Qx.buf, data->Qx.len, pabn_pubX[i]);
@@ -337,6 +345,8 @@ static int cryptomb_ssl_ecdsa_sigver(struct ecdsa_sigver_data *data, flags_t par
337345
data->sigver_success = 0;
338346
}
339347

348+
out:
349+
340350
return ret;
341351
}
342352

backends/backend_ippcrypto.c

Lines changed: 199 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,9 @@ static int ippcp_rsa_keygen_en(struct buffer *ebuf, uint32_t modulus, void **pri
688688
CKNULL_LOG((sts == ippStsNoErr), sts, "Error in ippcp_init_set_bn")
689689

690690
sts = ippsRSA_GenerateKeys(E0, N, E, D, pPrvKey, buffScratch.buf,
691-
0, pPrimeG, ippsPRNGen, pPRNG);
691+
0, pPrimeG, ippsPRNGenRDRAND, pPRNG);
692692
if(ippStsInsufficientEntropy == sts) {
693693
logger(LOGGER_WARN, "ippStsInsufficientEntropy\n");
694-
e0_data += 2;
695694
continue;
696695
}
697696
else {
@@ -1293,7 +1292,7 @@ static int ippcp_ecdsa_keygen_en(uint64_t curve, struct buffer *Qx_buf, struct b
12931292
Ipp32u isZeroRes;
12941293
do {
12951294
// get regular private key
1296-
sts = ippsGFpECPrivateKey(bnPrivate, pEC, ippsPRNGen, pRand);
1295+
sts = ippsGFpECPrivateKey(bnPrivate, pEC, ippsPRNGenRDRAND, pRand);
12971296
CKNULL_LOG((sts == ippStsNoErr), sts, "Error in ippsGFpECPrivateKey")
12981297

12991298
ippsCmpZero_BN(bnPrivate, &isZeroRes);
@@ -1480,7 +1479,7 @@ static int ippcp_ecdsa_siggen(struct ecdsa_siggen_data *data, flags_t parsed_fla
14801479

14811480
Ipp32u isZeroRes, isEquRes;
14821481
do { // get new ephemeral private key
1483-
sts = ippsGFpECPrivateKey(bnEphPrivate, pEC, ippsPRNGen, pRand);
1482+
sts = ippsGFpECPrivateKey(bnEphPrivate, pEC, ippsPRNGenRDRAND, pRand);
14841483
CKNULL_LOG((sts == ippStsNoErr), sts, "Error in ippsGFpECPrivateKey")
14851484
ippsCmpZero_BN(bnEphPrivate, &isZeroRes);
14861485
ippsCmp_BN(bnEphPrivate, bnRegPrivate, &isEquRes);
@@ -1741,3 +1740,199 @@ static void ippcp_ecdsa_backend(void)
17411740
{
17421741
register_ecdsa_impl(&ippcp_ecdsa);
17431742
}
1743+
1744+
/************************************************
1745+
* LMS interface functions
1746+
************************************************/
1747+
// fixed value
1748+
#define IPPCP_LMS_PK_I_BYTESIZE (16)
1749+
1750+
// stuff functions
1751+
static IppsLMSAlgo getIppsLMSAlgo(const struct buffer lmsMode, Ipp32u* hashByteSize) {
1752+
const char * lmsTypeStr = (const char *)lmsMode.buf;
1753+
if(strcmp(lmsTypeStr, "LMS_SHA256_M24_H5") == 0) {
1754+
*hashByteSize = 24;
1755+
return LMS_SHA256_M24_H5;
1756+
}
1757+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M24_H10") == 0) {
1758+
*hashByteSize = 24;
1759+
return LMS_SHA256_M24_H10;
1760+
}
1761+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M24_H15") == 0) {
1762+
*hashByteSize = 24;
1763+
return LMS_SHA256_M24_H15;
1764+
}
1765+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M24_H20") == 0) {
1766+
*hashByteSize = 24;
1767+
return LMS_SHA256_M24_H20;
1768+
}
1769+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M24_H25") == 0) {
1770+
*hashByteSize = 24;
1771+
return LMS_SHA256_M24_H25;
1772+
}
1773+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M32_H5") == 0) {
1774+
*hashByteSize = 32;
1775+
return LMS_SHA256_M32_H5;
1776+
}
1777+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M32_H10") == 0) {
1778+
*hashByteSize = 32;
1779+
return LMS_SHA256_M32_H10;
1780+
}
1781+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M32_H15") == 0) {
1782+
*hashByteSize = 32;
1783+
return LMS_SHA256_M32_H15;
1784+
}
1785+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M32_H20") == 0) {
1786+
*hashByteSize = 32;
1787+
return LMS_SHA256_M32_H20;
1788+
}
1789+
else if(strcmp(lmsTypeStr, "LMS_SHA256_M32_H25") == 0) {
1790+
*hashByteSize = 32;
1791+
return LMS_SHA256_M32_H25;
1792+
}
1793+
else {
1794+
*hashByteSize = 0;
1795+
return 0;
1796+
}
1797+
}
1798+
1799+
static IppsLMOTSAlgo getIppsLMOTSAlgo(const struct buffer lmOtsMode, Ipp32u* pCount) {
1800+
const char * lmotsTypeStr = (const char *)lmOtsMode.buf;
1801+
if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N24_W1") == 0) {
1802+
*pCount = 200;
1803+
return LMOTS_SHA256_N24_W1;
1804+
}
1805+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N24_W2") == 0) {
1806+
*pCount = 101;
1807+
return LMOTS_SHA256_N24_W2;
1808+
}
1809+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N24_W4") == 0) {
1810+
*pCount = 51;
1811+
return LMOTS_SHA256_N24_W4;
1812+
}
1813+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N24_W8") == 0) {
1814+
*pCount = 26;
1815+
return LMOTS_SHA256_N24_W8;
1816+
}
1817+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N32_W1") == 0) {
1818+
*pCount = 265;
1819+
return LMOTS_SHA256_N32_W1;
1820+
}
1821+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N32_W2") == 0) {
1822+
*pCount = 133;
1823+
return LMOTS_SHA256_N32_W2;
1824+
}
1825+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N32_W4") == 0) {
1826+
*pCount = 67;
1827+
return LMOTS_SHA256_N32_W4;
1828+
}
1829+
else if(strcmp(lmotsTypeStr, "LMOTS_SHA256_N32_W8") == 0) {
1830+
*pCount = 34;
1831+
return LMOTS_SHA256_N32_W8;
1832+
}
1833+
else {
1834+
*pCount = 0;
1835+
return 0;
1836+
}
1837+
}
1838+
1839+
static int ippcp_lms_sigver(struct lms_sigver_data *data, flags_t parsed_flags)
1840+
{
1841+
(void)parsed_flags;
1842+
IppStatus status = ippStsNoErr;
1843+
int ret = 0;
1844+
1845+
Ipp32u hashByteSize = 0;
1846+
Ipp32u pCount = 0;
1847+
const Ipp32s msgLen = data->msg.len;
1848+
1849+
Ipp8u* pScratchBuffer = NULL;
1850+
IppsLMSPublicKeyState* pPubKey = NULL;
1851+
IppsLMSSignatureState* pSignature = NULL;
1852+
1853+
IppsLMSAlgo lmsType = getIppsLMSAlgo(data->lmsMode, &hashByteSize);
1854+
IppsLMOTSAlgo lmotsType = getIppsLMOTSAlgo(data->lmOtsMode, &pCount);
1855+
const IppsLMSAlgoType lmsAlgType = { lmotsType, lmsType };
1856+
1857+
/* Allocate memory for the scratch buffer */
1858+
int buffSize;
1859+
status = ippsLMSBufferGetSize(&buffSize, msgLen, lmsAlgType);
1860+
CKNULL_LOG((status == ippStsNoErr), status, "Error in ippsLMSBufferGetSize")
1861+
pScratchBuffer = malloc(buffSize);
1862+
1863+
/* Parse public key vector */
1864+
IppsLMSAlgo lmsTypePk;
1865+
dataReverse((Ipp8u*)&lmsTypePk, (const char *)data->pub.buf, sizeof(Ipp32u));
1866+
1867+
IppsLMOTSAlgo lmotsTypePk;
1868+
dataReverse((Ipp8u*)&lmotsTypePk, (const char *)data->pub.buf+sizeof(Ipp32u), sizeof(Ipp32u));
1869+
const IppsLMSAlgoType lmsAlgTypePk = { lmotsTypePk, lmsTypePk };
1870+
1871+
const Ipp8u* pI = (const Ipp8u*)data->pub.buf + 2*sizeof(Ipp32u);
1872+
const Ipp8u* pK = pI + IPPCP_LMS_PK_I_BYTESIZE;
1873+
1874+
/* Allocate memory for the LMS public key state */
1875+
int ippcpPubKeySize;
1876+
status = ippsLMSPublicKeyStateGetSize(&ippcpPubKeySize, lmsAlgType);
1877+
CKNULL_LOG((status == ippStsNoErr), status, "Error in ippsLMSPublicKeyStateGetSize")
1878+
pPubKey = (IppsLMSPublicKeyState*)malloc(ippcpPubKeySize);
1879+
1880+
/* Set the LMS public key */
1881+
status = ippsLMSSetPublicKeyState(lmsAlgTypePk, pI, pK, pPubKey);
1882+
CKNULL_LOG((status == ippStsNoErr), status, "Error in ippsLMSSetPublicKeyState")
1883+
1884+
/* Parse signature vector */
1885+
Ipp32u q = 0;
1886+
dataReverse((Ipp8u*)&q, (const char *)data->sig.buf, sizeof(Ipp32u));
1887+
1888+
IppsLMOTSAlgo lmotsTypeSig;
1889+
dataReverse((Ipp8u*)&lmotsTypeSig, (const char *)data->sig.buf+sizeof(Ipp32u), sizeof(Ipp32u));
1890+
1891+
const Ipp8u* pC = (const Ipp8u*)data->sig.buf + 2*sizeof(Ipp32u);
1892+
const Ipp8u* pY = pC + hashByteSize;
1893+
1894+
IppsLMSAlgo lmsTypeSig;
1895+
dataReverse((Ipp8u*)&lmsTypeSig, (const char *)pY+hashByteSize*pCount, sizeof(Ipp32u));
1896+
1897+
const IppsLMSAlgoType lmsAlgTypeSig = { lmotsTypeSig, lmsTypeSig };
1898+
const Ipp8u* pAuthPath = pY + sizeof(Ipp32u) + hashByteSize*pCount;
1899+
1900+
/* Allocate memory for the LMS signature state */
1901+
int sigBuffSize;
1902+
status = ippsLMSSignatureStateGetSize(&sigBuffSize, lmsAlgTypeSig);
1903+
if(status != ippStsNoErr) { // Do not throw error, passed parameter in dataset may be intentionally invalid
1904+
data->sigver_success = 0;
1905+
goto out;
1906+
}
1907+
pSignature = (IppsLMSSignatureState*)malloc(sigBuffSize);
1908+
1909+
/* Set the LMS signature */
1910+
status = ippsLMSSetSignatureState(lmsAlgTypeSig, q, pC, pY, pAuthPath, pSignature);
1911+
if(status != ippStsNoErr) { // Do not throw error, passed parameter in dataset may be intentionally invalid
1912+
data->sigver_success = 0;
1913+
goto out;
1914+
}
1915+
1916+
int is_valid = 0;
1917+
/* Verify the LMS signature */
1918+
status = ippsLMSVerify(data->msg.buf, msgLen, pSignature, &is_valid, pPubKey, pScratchBuffer);
1919+
data->sigver_success = is_valid;
1920+
1921+
out:
1922+
free(pScratchBuffer);
1923+
free((Ipp8u*)pPubKey);
1924+
free((Ipp8u*)pSignature);
1925+
1926+
return ret;
1927+
}
1928+
1929+
static struct lms_backend ippcp_lms =
1930+
{
1931+
ippcp_lms_sigver /* lms_sigver */
1932+
};
1933+
1934+
ACVP_DEFINE_CONSTRUCTOR(ippcp_lms_backend)
1935+
static void ippcp_lms_backend(void)
1936+
{
1937+
register_lms_impl(&ippcp_lms);
1938+
}

backends/backend_ippcrypto_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
/* Useful defines */
2626

2727
#define IPPCP_DATA_ALIGNMENT ((int)sizeof(void *))
28-
static __inline Ipp64s IPP_INT_PTR( const void* ptr )
28+
static Ipp64s IPP_INT_PTR( const void* ptr )
2929
{
3030
union {
3131
void* Ptr;

0 commit comments

Comments
 (0)