Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify the implementation of KEMs and Kyber #605

Merged
merged 11 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ add_library(
ex_data.c
hpke/hpke.c
hrss/hrss.c
kyber/kem_kyber_512.c
kyber/kem_kyber512.c
kyber/p_kyber.c
kyber/p_kyber512_asn1.c
kyber/pqcrystals-kyber_kyber512_ref/cbd.c
Expand Down
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,6 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = {
NULL /* derive */,
NULL /* paramgen */,
NULL /* ctrl */,
NULL /* encapsulate */,
NULL /* decapsulate */,
};
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_hkdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ const EVP_PKEY_METHOD hkdf_pkey_meth = {
pkey_hkdf_derive,
/*paramgen=*/NULL,
pkey_hkdf_ctrl,
/*encapsulate*/NULL,
andrewhop marked this conversation as resolved.
Show resolved Hide resolved
/*decapsulate*/NULL,
};

int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) {
Expand Down
2 changes: 2 additions & 0 deletions crypto/evp_extra/p_x25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,6 @@ const EVP_PKEY_METHOD x25519_pkey_meth = {
pkey_x25519_derive,
NULL /* paramgen */,
pkey_x25519_ctrl,
NULL /* encapsulate */,
NULL /* decapsulate */,
};
20 changes: 8 additions & 12 deletions crypto/evp_extra/pq_kem_kat_tests_kyber512.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ static void RunTest(FileTest *t)
std::string count;
std::vector<uint8_t> seed, pk, sk, ct, ss;

size_t shared_secret_len = KYBER512_KEM_SHARED_SECRET_BYTES;
size_t ciphertext_len = KYBER512_KEM_CIPHERTEXT_BYTES;
uint8_t shared_secret[KYBER512_KEM_SHARED_SECRET_BYTES];
uint8_t ciphertext[KYBER512_KEM_CIPHERTEXT_BYTES];
size_t shared_secret_len = KYBER512_SHARED_SECRET_BYTES;
size_t ciphertext_len = KYBER512_CIPHERTEXT_BYTES;
uint8_t shared_secret[KYBER512_SHARED_SECRET_BYTES];
uint8_t ciphertext[KYBER512_CIPHERTEXT_BYTES];

ASSERT_TRUE(t->GetAttribute(&count, "count"));
ASSERT_TRUE(t->GetBytes(&seed, "seed"));
Expand All @@ -40,19 +40,15 @@ static void RunTest(FileTest *t)
EXPECT_EQ(Bytes(pk),
Bytes(kyber512Key->pub, KYBER512_PUBLIC_KEY_BYTES));
EXPECT_EQ(Bytes(sk),
Bytes(kyber512Key->priv, KYBER512_PRIVATE_KEY_BYTES));
Bytes(kyber512Key->priv, KYBER512_SECRET_KEY_BYTES));

ASSERT_TRUE(EVP_PKEY_encapsulate_init(kyber_pkey_ctx, NULL));
ASSERT_TRUE(EVP_PKEY_encapsulate(kyber_pkey_ctx, ciphertext, &ciphertext_len, shared_secret, &shared_secret_len));
EXPECT_EQ(Bytes(ct),
Bytes(ciphertext, KYBER512_KEM_CIPHERTEXT_BYTES));
//Specifically free the KEM because decapsulate_init on the reused ctx will
//allocate a new one, orphaning this one.
OPENSSL_free(kyber_pkey_ctx->op.encap.kem);
ASSERT_TRUE(EVP_PKEY_decapsulate_init(kyber_pkey_ctx, NULL));
Bytes(ciphertext, KYBER512_CIPHERTEXT_BYTES));

ASSERT_TRUE(EVP_PKEY_decapsulate(kyber_pkey_ctx, shared_secret, &shared_secret_len, ciphertext, ciphertext_len));
EXPECT_EQ(Bytes(ss),
Bytes(shared_secret, KYBER512_KEM_SHARED_SECRET_BYTES));
Bytes(shared_secret, KYBER512_SHARED_SECRET_BYTES));

EVP_PKEY_CTX_free(kyber_pkey_ctx);
}
Expand Down
1 change: 0 additions & 1 deletion crypto/fipsmodule/evp/evp_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) {
}
EVP_PKEY_free(ctx->pkey);
EVP_PKEY_free(ctx->peerkey);
OPENSSL_free(ctx->op.encap.kem);
OPENSSL_free(ctx);
}

Expand Down
21 changes: 10 additions & 11 deletions crypto/fipsmodule/evp/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,6 @@ struct evp_pkey_ctx_st {
int operation;
// Algorithm specific data
void *data;

// Currently, only the KEM operations are supported through this op variable.
// As more operations are added or migrated over to the OpenSSL 3 style, this
// union can be augmented with additional operation structures
// (e.g. encryption, signing)
union {
struct {
EVP_KEM *kem;
void *algctx; // opaque KEM-specific context
} encap;
} op;
}; // EVP_PKEY_CTX

struct evp_pkey_method_st {
Expand Down Expand Up @@ -255,6 +244,16 @@ struct evp_pkey_method_st {
int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);

int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);

// Encapsulate and decapsulate are operations defined for a
// Key Encapsulation Mechanism (KEM).
int (*encapsulate)(EVP_PKEY_CTX *ctx,
uint8_t *ciphertext, size_t *ciphertext_len,
uint8_t *shared_secret, size_t *shared_secret_len);

int (*decapsulate)(EVP_PKEY_CTX *ctx,
uint8_t *shared_secret, size_t *shared_secret_len,
const uint8_t *ciphertext, size_t ciphertext_len);
}; // EVP_PKEY_METHOD

#define FIPS_EVP_PKEY_METHODS 3
Expand Down
84 changes: 17 additions & 67 deletions crypto/fipsmodule/evp/kem.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,28 @@
#include <openssl/evp.h>
#include <openssl/mem.h>

#define SUCCESS (1)
#define FAILURE (0)

static int kem_fetch(unsigned int algorithm_type, EVP_KEM *kem) {
int ret = FAILURE;
switch (algorithm_type) {
case NID_KYBER512:
*kem = EVP_KEM_kyber512;
ret = SUCCESS;
break;
default:
ret = FAILURE;
}
return ret;
}

int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) {
EVP_KEM *kem = OPENSSL_malloc(sizeof(EVP_KEM));
if (kem == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return FAILURE;
}

if (ctx != NULL &&
ctx->pkey != NULL &&
kem_fetch(ctx->pkey->type, kem) &&
kem->encapsulate_init(ctx, ctx->pkey, params)) {
ctx->op.encap.kem = kem;
return SUCCESS;
} else {
OPENSSL_free(kem);
return FAILURE;
}
}

int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *out_len,
unsigned char *secret, size_t *secret_len) {
if (ctx != NULL &&
ctx->op.encap.kem != NULL &&
ctx->op.encap.kem->encapsulate != NULL) {
return ctx->op.encap.kem->encapsulate(ctx, out, out_len, secret, secret_len);
uint8_t *ciphertext, size_t *ciphertext_len,
uint8_t *shared_secret, size_t *shared_secret_len) {
if (ctx == NULL ||
ctx->pmeth == NULL ||
ctx->pmeth->encapsulate == NULL) {
return 0;
}
return FAILURE;
}

int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) {
EVP_KEM *kem = OPENSSL_malloc(sizeof(EVP_KEM));
if (kem == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return FAILURE;
}

if (ctx != NULL &&
ctx->pkey != NULL &&
kem_fetch(ctx->pkey->type, kem) &&
kem->decapsulate_init(ctx, ctx->pkey, params)) {
ctx->op.encap.kem = kem;
return SUCCESS;
} else {
OPENSSL_free(kem);
return FAILURE;
}
return ctx->pmeth->encapsulate(ctx, ciphertext, ciphertext_len,
shared_secret, shared_secret_len);
}

int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx,
unsigned char *secret, size_t *secret_len,
const unsigned char *in, size_t in_len) {
if (ctx != NULL &&
ctx->op.encap.kem != NULL &&
ctx->op.encap.kem->decapsulate != NULL) {
return ctx->op.encap.kem->decapsulate(ctx, secret, secret_len, in, in_len);
uint8_t *shared_secret, size_t *shared_secret_len,
uint8_t *ciphertext, size_t ciphertext_len) {
if (ctx == NULL ||
ctx->pmeth == NULL ||
ctx->pmeth->decapsulate == NULL) {
return 0;
}
return FAILURE;

return ctx->pmeth->decapsulate(ctx, shared_secret, shared_secret_len,
ciphertext, ciphertext_len);
}
34 changes: 14 additions & 20 deletions crypto/kyber/kem_kyber.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,23 @@
#include <openssl/base.h>
#include <openssl/evp.h>

#define KYBER512_PRIVATE_KEY_BYTES 1632
// The values below are taken from the |api.h| file in the
// |crypto/kyber/pqcrystals-kyber_kyber512_ref| directory.
#define KYBER512_PUBLIC_KEY_BYTES 800
#define KYBER512_KEM_CIPHERTEXT_BYTES 768
#define KYBER512_KEM_SHARED_SECRET_BYTES 32
#define KYBER512_SECRET_KEY_BYTES 1632
#define KYBER512_CIPHERTEXT_BYTES 768
#define KYBER512_SHARED_SECRET_BYTES 32

int kyber512_keypair(uint8_t *public_key, uint8_t *secret_key);
int kyber512_keypair(uint8_t *public_key /* OUT */,
torben-hansen marked this conversation as resolved.
Show resolved Hide resolved
uint8_t *secret_key /* OUT */);

int kyber512_encapsulate_init(void *ctx,
void *prov_key,
const OSSL_PARAM params[]);
int kyber512_encapsulate(void *ctx,
unsigned char *out,
size_t *out_len,
unsigned char *secret,
size_t *secret_len);
int kyber512_decapsulate_init(void *ctx,
void *prov_key,
const OSSL_PARAM params[]);
int kyber512_decapsulate(void *ctx,
unsigned char *out,
size_t *out_len,
const unsigned char *in,
size_t in_len);
int kyber512_encapsulate(uint8_t *ciphertext /* OUT */,
uint8_t *shared_secret /* OUT */,
const uint8_t *public_key /* IN */);

int kyber512_decapsulate(uint8_t *shared_secret /* OUT */,
const uint8_t *ciphertext /* IN */,
const uint8_t *secret_key /* IN */);

#endif

27 changes: 27 additions & 0 deletions crypto/kyber/kem_kyber512.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "../evp_extra/internal.h"
#include "../fipsmodule/evp/internal.h"
#include "kem_kyber.h"
#include "pqcrystals-kyber_kyber512_ref/api.h"
andrewhop marked this conversation as resolved.
Show resolved Hide resolved

// Note: These methods currently default to using the reference code for Kyber.
// In a future where AWS-LC has optimized options available, those can be
// conditionally (or based on compile-time flags) called here, depending on
// platform support.

int kyber512_keypair(uint8_t *public_key /* OUT */,
uint8_t *secret_key /* OUT */) {
return pqcrystals_kyber512_ref_keypair(public_key, secret_key);
}

int kyber512_encapsulate(uint8_t *ciphertext /* OUT */,
uint8_t *shared_secret /* OUT */,
const uint8_t *public_key /* IN */) {
return pqcrystals_kyber512_ref_enc(ciphertext, shared_secret, public_key);
}

int kyber512_decapsulate(uint8_t *shared_secret /* OUT */,
const uint8_t *ciphertext /* IN */,
const uint8_t *secret_key /* IN */) {
return pqcrystals_kyber512_ref_dec(shared_secret, ciphertext, secret_key);
}

94 changes: 0 additions & 94 deletions crypto/kyber/kem_kyber_512.c

This file was deleted.

Loading