"sxops" interface for DSA cryptographic computations
Simpler functions to perform public key crypto operations. Included directly in some interfaces (like sxbuf or OpenSSL engine). The functions take input operands (large integers) and output operands which will get the computed results.
Operands have the "sx_op" type. The specific interfaces (like sxbuf) define the "sx_op" type.
@file
DSA_HEADER_FILE Macro
C
#define DSA_HEADER_FILE
/ Copyright (c) 2020 Silex Insight sa SPDX-License-Identifier: BSD-3-Clause
Make sure the application is compatible with SilexPK API version **/
SX_PK_API_ASSERT_COMPATIBLE(1, 1);
struct sx_pk_cmd_def;
@addtogroup SX_PK_SXOPS_DSA
@{
Asynchronous (non-blocking) DSA signature generation
Start an DSA signature generation on the accelerator and return immediately.
@remark When the operation finishes on the accelerator, call sx_async_finish_pair()
Parameters
cnx Connection structure obtained through SX_PK_OPEN() at startup
Parameters
p Prime modulus p
Parameters
q Prime divisor of p-1
Parameters
g Generator of order q mod p
Parameters
k Random value
Parameters
privkey Private key
Parameters
h Hash digest of message reduced by means of Secure Hash Algorithm specified in FIPS 180-3 @return Acquired acceleration request for this operation @see sx_dsa_sign() for a synchronous version static inline struct sx_pk_dreq sx_async_dsa_sign_go(struct sx_pk_cnx cnx, const sx_op p, const sx_op q, const sx_op g, const sx_op k, const sx_op privkey, const sx_op h) { struct sx_pk_dreq pkreq; struct sx_pk_inops_dsa_sign inputs; pkreq = SX_PK_ACQUIRE_REQ(cnx, SX_PK_CMD_DSA_SIGN); if (pkreq.status) return pkreq; // convert and transfer operands int sizes = { SX_OP_SIZE(p), SX_OP_SIZE(q), SX_OP_SIZE(g), SX_OP_SIZE(k), SX_OP_SIZE(privkey), SX_OP_SIZE(h), }; pkreq.status = SX_PK_LIST_GFP_INSLOTS(pkreq.req, sizes, (struct sx_pk_slot )&inputs); if (pkreq.status) return pkreq; SX_PK_OP2VMEM(p, inputs.p.addr); SX_PK_OP2VMEM(q, inputs.q.addr); SX_PK_OP2VMEM(g, inputs.g.addr); SX_PK_OP2VMEM(k, inputs.k.addr); SX_PK_OP2VMEM(privkey, inputs.privkey.addr); SX_PK_OP2VMEM(h, inputs.h.addr); SX_PK_RUN(pkreq.req); return pkreq; }
DSA signature generation
Computes the following: 1. X = g k mod p 2. r = X mod q 3. if r == 0 the return ::SX_ERR_INVALID_SIGNATURE 4. else w = k (-1) mod q 5. s = w (h + x r) mod q 6. if s == 0 then return ::SX_ERR_INVALID_SIGNATURE 7. (r,s) is the signature
Parameters
cnx Connection structure obtained through SX_PK_OPEN() at startup
Parameters
p Prime modulus p
Parameters
q Prime divisor of p-1
Parameters
g Generator of order q mod p
Parameters
k Random value
Parameters
privkey Private key
Parameters
h Hash digest of message reduced by means of Secure Hash Algorithm specified in FIPS 180-3
Parameters
r First part of signature
Parameters
s Second part of signature @return ::SX_OK @return ::SX_ERR_NOT_INVERTIBLE @return ::SX_ERR_INVALID_SIGNATURE @return ::SX_ERR_INVALID_PARAM @return ::SX_ERR_UNKNOWN_ERROR @return ::SX_ERR_BUSY @return ::SX_ERR_NOT_IMPLEMENTED @return ::SX_ERR_OPERAND_TOO_LARGE @return ::SX_ERR_PLATFORM_ERROR @return ::SX_ERR_EXPIRED @see sx_async_dsa_sign_go() for an asynchronous version int sx_dsa_sign(struct sx_pk_cnx cnx, const sx_op p, const sx_op q, const sx_op g, const sx_op k, const sx_op privkey, const sx_op h, sx_op r, sx_op s) { struct sx_pk_dreq pkreq; int status; pkreq = sx_async_dsa_sign_go(cnx, p, q, g, k, privkey, h); if (pkreq.status) return pkreq.status; status = SX_PK_WAIT(pkreq.req); sx_async_finish_pair(pkreq.req, r, s); return status; }
Asynchronous (non-blocking) DSA signature verification
Start an DSA signature verification on the accelerator and return immediately. @remark When the operation finishes on the accelerator, call SX_PK_RELEASE_REQ()
Parameters
cnx Connection structure obtained through SX_PK_OPEN() at startup
Parameters
p Prime modulus p
Parameters
q Prime divisor of p-1
Parameters
g Generator of order q mod p
Parameters
pubkey Public key
Parameters
h Hash digest of message reduced by means of Secure Hash Algorithm specified in FIPS 180-3
Parameters
r First part of the signature to verify
Parameters
s Second part of the signature to verify @return Acquired acceleration request for this operation @see sx_dsa_ver() for a synchronous version static inline struct sx_pk_dreq sx_async_dsa_ver_go(struct sx_pk_cnx cnx, const sx_op p, const sx_op q, const sx_op g, const sx_op pubkey, const sx_op h, const sx_op r, const sx_op s) { struct sx_pk_dreq pkreq; struct sx_pk_inops_dsa_ver inputs; pkreq = SX_PK_ACQUIRE_REQ(cnx, SX_PK_CMD_DSA_VER); if (pkreq.status) return pkreq; // convert and transfer operands int sizes = { SX_OP_SIZE(p), SX_OP_SIZE(q), SX_OP_SIZE(g), SX_OP_SIZE(pubkey), SX_OP_SIZE(h), SX_OP_SIZE(r), SX_OP_SIZE(s), }; pkreq.status = SX_PK_LIST_GFP_INSLOTS(pkreq.req, sizes, (struct sx_pk_slot )&inputs); if (pkreq.status) return pkreq; SX_PK_OP2VMEM(p, inputs.p.addr); SX_PK_OP2VMEM(q, inputs.q.addr); SX_PK_OP2VMEM(g, inputs.g.addr); SX_PK_OP2VMEM(pubkey, inputs.pubkey.addr); SX_PK_OP2VMEM(h, inputs.h.addr); SX_PK_OP2VMEM(r, inputs.r.addr); SX_PK_OP2VMEM(s, inputs.s.addr); SX_PK_RUN(pkreq.req); return pkreq; }
DSA signature verification
Checks if a signature is valid: 1. w = s (-1) mod q 2. u1 = h w mod q 3. u2 = r w mod q 4. X = g (u1) y (u2) mod p 5. v = X mod q 6. if v == r then signature is valid (::SX_OK) 7. else return ::SX_ERR_INVALID_SIGNATURE Before launching the operation, verify the domain D(p,q,g) by checking: 1. 21023 < p < 21024 \b or 22047 < p < 22048 2. 2159 < q < 2160 \b or 2223 < q < 2224 \b or 2255 < q < 2^256 3. 1 < g < p
Parameters
cnx Connection structure obtained through SX_PK_OPEN() at startup
Parameters
p Prime modulus p
Parameters
q Prime divisor of p-1
Parameters
g Generator of order q mod p
Parameters
pubkey Public key
Parameters
h Hash digest of message reduced by means of Secure Hash Algorithm specified in FIPS 180-3
Parameters
r First part of the signature to verify
Parameters
s Second part of the signature to verify @return ::SX_OK @return ::SX_ERR_NOT_INVERTIBLE @return ::SX_ERR_INVALID_SIGNATURE @return ::SX_ERR_OUT_OF_RANGE @return ::SX_ERR_INVALID_PARAM @return ::SX_ERR_UNKNOWN_ERROR @return ::SX_ERR_BUSY @return ::SX_ERR_NOT_IMPLEMENTED @return ::SX_ERR_OPERAND_TOO_LARGE @return ::SX_ERR_PLATFORM_ERROR @return ::SX_ERR_EXPIRED @see sx_async_dsa_ver_go() for an asynchronous version int sx_dsa_ver(struct sx_pk_cnx cnx, const sx_op p, const sx_op q, const sx_op g, const sx_op pubkey, const sx_op h, const sx_op r, const sx_op s) { struct sx_pk_dreq pkreq; int status; pkreq = sx_async_dsa_ver_go(cnx, p, q, g, pubkey, h, r, s); if (pkreq.status) return pkreq.status; status = SX_PK_WAIT(pkreq.req); SX_PK_RELEASE_REQ(pkreq.req); return status; }}