#include "crypto/lms_sig.h"
#include "crypto/lms_util.h"
LMS_SIG *ossl_lms_sig_from_pkt(PACKET *pkt, const LMS_KEY *pub)
{
uint32_t sig_ots_type = 0, sig_lms_type = 0;
const LMS_PARAMS *lparams = pub->lms_params;
const LM_OTS_PARAMS *pub_ots_params = pub->ots_params;
const LM_OTS_PARAMS *sig_params;
LMS_SIG *lsig = NULL;
lsig = ossl_lms_sig_new();
if (lsig == NULL)
return NULL;
if (!PACKET_get_net_4_len_u32(pkt, &lsig->q)
|| !PACKET_get_net_4_len_u32(pkt, &sig_ots_type)
|| pub_ots_params->lm_ots_type != sig_ots_type)
goto err;
sig_params = pub_ots_params;
lsig->sig.params = sig_params;
lsig->params = lparams;
if (!PACKET_get_bytes(pkt, (const unsigned char **)&lsig->sig.C,
sig_params->n)
|| !PACKET_get_bytes(pkt, (const unsigned char **)&lsig->sig.y,
sig_params->p * sig_params->n)
|| !PACKET_get_net_4_len_u32(pkt, &sig_lms_type)
|| (lparams->lms_type != sig_lms_type)
|| HASH_NOT_MATCHED(lparams, sig_params)
|| lsig->q >= (uint32_t)(1 << lparams->h)
|| !PACKET_get_bytes(pkt, (const unsigned char **)&lsig->paths,
lparams->h * lparams->n)
|| PACKET_remaining(pkt) > 0)
goto err;
return lsig;
err:
ossl_lms_sig_free(lsig);
return NULL;
}
int ossl_lms_sig_decode(LMS_SIG **out, LMS_KEY *pub,
const unsigned char *sig, size_t siglen)
{
PACKET pkt;
LMS_SIG *s = NULL;
if (pub == NULL)
return 0;
if (!PACKET_buf_init(&pkt, sig, siglen))
return 0;
s = ossl_lms_sig_from_pkt(&pkt, pub);
if (s == NULL)
return 0;
if (PACKET_remaining(&pkt) > 0)
goto err;
*out = s;
return 1;
err:
ossl_lms_sig_free(s);
return 0;
}