diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -948,7 +948,8 @@ crypto_driver.9 CRYPTODEV_PROCESS.9 \ crypto_driver.9 hmac_init_ipad.9 \ crypto_driver.9 hmac_init_opad.9 -MLINKS+=crypto_request.9 crypto_destroyreq.9 \ +MLINKS+=crypto_request.9 crypto_clonereq.9 \ + crypto_request.9 crypto_destroyreq.9 \ crypto_request.9 crypto_dispatch.9 \ crypto_request.9 crypto_freereq.9 \ crypto_request.9 crypto_getreq.9 \ diff --git a/share/man/man9/crypto_request.9 b/share/man/man9/crypto_request.9 --- a/share/man/man9/crypto_request.9 +++ b/share/man/man9/crypto_request.9 @@ -38,6 +38,8 @@ .Nd symmetric cryptographic operations .Sh SYNOPSIS .In opencrypto/cryptodev.h +.Ft "struct cryptop *" +.Fn crypto_clonereq "crypto_session_t cses" "struct cryptop *crp" "int how" .Ft int .Fn crypto_dispatch "struct cryptop *crp" .Ft int @@ -76,8 +78,10 @@ .Pp Requests can either be allocated dynamically or use caller-supplied storage. -Dynamically allocated requests should be allocated by +Dynamically allocated requests should be allocated by either .Fn crypto_getreq +or +.Fn crypto_clonereq , and freed by .Fn crypto_freereq once the request has completed. @@ -87,13 +91,16 @@ .Fn crypto_destroyreq once the request has completed. .Pp -For both -.Fn crypto_getreq +For +.Fn crypto_clonereq , +.Fn crypto_getreq , and .Fn crypto_initreq , .Fa cses is a reference to an active session. For +.Fn crypto_clonereq +and .Fn crypto_getreq , .Fa how is passed to @@ -103,6 +110,18 @@ or .Dv M_WAITOK . .Pp +.Fn crypto_clonereq +allocates a new request that inherits request inputs such as request buffers +from the original +.Fa crp +request. +However, the new request is associated with the +.Fa cses +session rather than inheriting the session from +.Fa crp . +.Fa crp +must not be a completed request. +.Pp Once a request has been initialized, the caller should set fields in the structure to describe request-specific parameters. diff --git a/sys/opencrypto/crypto.c b/sys/opencrypto/crypto.c --- a/sys/opencrypto/crypto.c +++ b/sys/opencrypto/crypto.c @@ -1627,6 +1627,27 @@ return (crp); } +/* + * Clone a crypto request, but associate it with the specified session + * rather than inheriting the session from the original request. The + * fields describing the request buffers are copied, but not the + * opaque field or callback function. + */ +struct cryptop * +crypto_clonereq(struct cryptop *crp, crypto_session_t cses, int how) +{ + struct cryptop *new; + + MPASS((crp->crp_flags & CRYPTO_F_DONE) == 0); + new = crypto_getreq(cses, how); + if (new == NULL) + return (NULL); + + memcpy(&new->crp_startcopy, &crp->crp_startcopy, + __rangeof(struct cryptop, crp_startcopy, crp_endcopy)); + return (new); +} + /* * Invoke the callback on behalf of the driver. */ diff --git a/sys/opencrypto/cryptodev.h b/sys/opencrypto/cryptodev.h --- a/sys/opencrypto/cryptodev.h +++ b/sys/opencrypto/cryptodev.h @@ -425,6 +425,7 @@ * should always check and use the new * value on future requests. */ +#define crp_startcopy crp_flags int crp_flags; #define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */ @@ -457,6 +458,7 @@ const void *crp_cipher_key; /* New cipher key if non-NULL. */ const void *crp_auth_key; /* New auth key if non-NULL. */ +#define crp_endcopy crp_opaque void *crp_opaque; /* Opaque pointer, passed along */ @@ -622,6 +624,8 @@ int crypto_unblock(uint32_t, int); void crypto_done(struct cryptop *crp); +struct cryptop *crypto_clonereq(struct cryptop *crp, crypto_session_t cses, + int how); void crypto_destroyreq(struct cryptop *crp); void crypto_initreq(struct cryptop *crp, crypto_session_t cses); void crypto_freereq(struct cryptop *crp);