Skip to content

Commit

Permalink
Support of en/decapsulation in the pkeyutl command
Browse files Browse the repository at this point in the history
  • Loading branch information
beldmit committed Aug 7, 2024
1 parent 5854b76 commit b5c2fbc
Showing 1 changed file with 57 additions and 8 deletions.
65 changes: 57 additions & 8 deletions apps/pkeyutl.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,

static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
unsigned char *out, size_t *poutlen,
const unsigned char *in, size_t inlen);
const unsigned char *in, size_t inlen,
unsigned char *secret, size_t *psecretlen);

static int do_raw_keyop(int pkey_op, EVP_MD_CTX *mctx,
EVP_PKEY *pkey, BIO *in,
Expand All @@ -47,6 +48,7 @@ typedef enum OPTION_choice {
OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_PKEYOPT_PASSIN, OPT_KDF,
OPT_KDFLEN, OPT_R_ENUM, OPT_PROV_ENUM,
OPT_DECAP, OPT_ENCAP, OPT_SECOUT,
OPT_CONFIG,
OPT_RAWIN, OPT_DIGEST
} OPTION_CHOICE;
Expand All @@ -64,6 +66,8 @@ const OPTIONS pkeyutl_options[] = {
{"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"},
{"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"},
{"derive", OPT_DERIVE, '-', "Derive shared secret"},
{"decap", OPT_DECAP, '-', "Decapsulate shared secret"},
{"encap", OPT_ENCAP, '-', "Encapsulate shared secret"},
OPT_CONFIG_OPTION,

OPT_SECTION("Input"),
Expand All @@ -81,6 +85,7 @@ const OPTIONS pkeyutl_options[] = {

OPT_SECTION("Output"),
{"out", OPT_OUT, '>', "Output file - default stdout"},
{"secret", OPT_SECOUT, '>', "Secret file (encapsulation/decapsulation)"},
{"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"},
{"hexdump", OPT_HEXDUMP, '-', "Hex dump output"},
{"verifyrecover", OPT_VERIFYRECOVER, '-',
Expand All @@ -103,20 +108,20 @@ const OPTIONS pkeyutl_options[] = {
int pkeyutl_main(int argc, char **argv)
{
CONF *conf = NULL;
BIO *in = NULL, *out = NULL;
BIO *in = NULL, *out = NULL, *secout = NULL;
ENGINE *e = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *pkey = NULL;
char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
char *infile = NULL, *outfile = NULL, *secoutfile = NULL, *sigfile = NULL, *passinarg = NULL;
char hexdump = 0, asn1parse = 0, rev = 0, *prog;
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL, *secret = NULL;
OPTION_CHOICE o;
int buf_inlen = 0, siglen = -1;
int keyform = FORMAT_UNDEF, peerform = FORMAT_UNDEF;
int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
int engine_impl = 0;
int ret = 1, rv = -1;
size_t buf_outlen;
size_t buf_outlen = 0, secretlen = 0;
const char *inkey = NULL;
const char *peerkey = NULL;
const char *kdfalg = NULL, *digestname = NULL;
Expand Down Expand Up @@ -147,6 +152,9 @@ int pkeyutl_main(int argc, char **argv)
case OPT_OUT:
outfile = opt_arg();
break;
case OPT_SECOUT:
secoutfile = opt_arg();
break;
case OPT_SIGFILE:
sigfile = opt_arg();
break;
Expand Down Expand Up @@ -216,6 +224,12 @@ int pkeyutl_main(int argc, char **argv)
case OPT_DERIVE:
pkey_op = EVP_PKEY_OP_DERIVE;
break;
case OPT_DECAP:
pkey_op = EVP_PKEY_OP_DECAPSULATE;
break;
case OPT_ENCAP:
pkey_op = EVP_PKEY_OP_ENCAPSULATE;
break;
case OPT_KDF:
pkey_op = EVP_PKEY_OP_DERIVE;
key_type = KEY_NONE;
Expand Down Expand Up @@ -402,6 +416,18 @@ int pkeyutl_main(int argc, char **argv)
if (out == NULL)
goto end;

if (secoutfile == NULL) {
if (pkey_op == EVP_PKEY_OP_ENCAPSULATE || pkey_op == EVP_PKEY_OP_DECAPSULATE) {
BIO_printf(bio_err,
"Encapsulation/decapsulation requires '-secoutfile' argument\n");
goto end;
}
} else {
secout = bio_open_default(secoutfile, 'w', FORMAT_BINARY);
if (secout == NULL)
goto end;
}

if (sigfile != NULL) {
BIO *sigbio = BIO_new_file(sigfile, "rb");

Expand Down Expand Up @@ -473,13 +499,15 @@ int pkeyutl_main(int argc, char **argv)
rv = 1;
} else {
rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
buf_in, (size_t)buf_inlen);
buf_in, (size_t)buf_inlen, NULL, (size_t *)&secretlen);
}
if (rv > 0 && buf_outlen != 0) {
buf_out = app_malloc(buf_outlen, "buffer output");
if (secretlen > 0)
secret = app_malloc(secretlen, "secret output");
rv = do_keyop(ctx, pkey_op,
buf_out, (size_t *)&buf_outlen,
buf_in, (size_t)buf_inlen);
buf_in, (size_t)buf_inlen, secret, (size_t *)&secretlen);
}
}
if (rv <= 0) {
Expand All @@ -500,6 +528,8 @@ int pkeyutl_main(int argc, char **argv)
} else {
BIO_write(out, buf_out, buf_outlen);
}
if (secretlen > 0)
BIO_write(secout, secret, secretlen);

end:
if (ret != 0)
Expand All @@ -510,9 +540,11 @@ int pkeyutl_main(int argc, char **argv)
release_engine(e);
BIO_free(in);
BIO_free_all(out);
BIO_free_all(secout);
OPENSSL_free(buf_in);
OPENSSL_free(buf_out);
OPENSSL_free(sig);
OPENSSL_free(secret);
sk_OPENSSL_STRING_free(pkeyopts);
sk_OPENSSL_STRING_free(pkeyopts_passin);
NCONF_free(conf);
Expand Down Expand Up @@ -642,6 +674,14 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
case EVP_PKEY_OP_DERIVE:
rv = EVP_PKEY_derive_init(ctx);
break;

case EVP_PKEY_OP_ENCAPSULATE:
rv = EVP_PKEY_encapsulate_init(ctx, NULL);
break;

case EVP_PKEY_OP_DECAPSULATE:
rv = EVP_PKEY_decapsulate_init(ctx, NULL);
break;
}
}

Expand Down Expand Up @@ -679,7 +719,8 @@ static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,

static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
unsigned char *out, size_t *poutlen,
const unsigned char *in, size_t inlen)
const unsigned char *in, size_t inlen,
unsigned char *secret, size_t *pseclen)
{
int rv = 0;
switch (pkey_op) {
Expand All @@ -703,6 +744,14 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
rv = EVP_PKEY_derive(ctx, out, poutlen);
break;

case EVP_PKEY_OP_ENCAPSULATE:
rv = EVP_PKEY_encapsulate(ctx, out, poutlen, secret, pseclen);
break;

case EVP_PKEY_OP_DECAPSULATE:
rv = EVP_PKEY_decapsulate(ctx, out, poutlen, in, inlen);
break;

}
return rv;
}
Expand Down

0 comments on commit b5c2fbc

Please sign in to comment.