Commit bd4ef1c9 authored by Kevin Jacobs's avatar Kevin Jacobs

Bug 1631890 - Add support for Hybrid Public Key Encryption (draft-irtf-cfrg-hpke-05). r=mt

This patch adds support for Hybrid Public Key Encryption (draft-irtf-cfrg-hpke-05).

Because the draft number (and the eventual RFC number) is an input to the key schedule, future updates will *not* be backwards compatible in terms of key material or encryption/decryption. For this reason, a default compilation will produce stubs that simply return an "Invalid Algorithm" error. To opt into using the HPKE functionality , compile with `NSS_ENABLE_DRAFT_HPKE` defined. Once finalized, this flag will not be required to access the functions.

Lastly, the `DeriveKeyPair` API is not implemented as it adds complextiy around PKCS #11 and is unnecessary for ECH.

Differential Revision: https://phabricator.services.mozilla.com/D73947

--HG--
extra : moz-landing-system : lando
parent 0504d1c8
1 Added function:
12 Added functions:
[A] 'function SECStatus PK11_HPKE_Deserialize(const HpkeContext*, const PRUint8*, unsigned int, SECKEYPublicKey**)' {PK11_HPKE_Deserialize@@NSS_3.58}
[A] 'function void PK11_HPKE_DestroyContext(HpkeContext*, PRBool)' {PK11_HPKE_DestroyContext@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_ExportSecret(const HpkeContext*, const SECItem*, unsigned int, PK11SymKey**)' {PK11_HPKE_ExportSecret@@NSS_3.58}
[A] 'function const SECItem* PK11_HPKE_GetEncapPubKey(const HpkeContext*)' {PK11_HPKE_GetEncapPubKey@@NSS_3.58}
[A] 'function HpkeContext* PK11_HPKE_NewContext(HpkeKemId, HpkeKdfId, HpkeAeadId, PK11SymKey*, const SECItem*)' {PK11_HPKE_NewContext@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_Open(HpkeContext*, const SECItem*, const SECItem*, SECItem**)' {PK11_HPKE_Open@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_Seal(HpkeContext*, const SECItem*, const SECItem*, SECItem**)' {PK11_HPKE_Seal@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_Serialize(const SECKEYPublicKey*, PRUint8*, unsigned int*, unsigned int)' {PK11_HPKE_Serialize@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_SetupR(HpkeContext*, const SECKEYPublicKey*, SECKEYPrivateKey*, const SECItem*, const SECItem*)' {PK11_HPKE_SetupR@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_SetupS(HpkeContext*, const SECKEYPublicKey*, SECKEYPrivateKey*, SECKEYPublicKey*, const SECItem*)' {PK11_HPKE_SetupS@@NSS_3.58}
[A] 'function SECStatus PK11_HPKE_ValidateParameters(HpkeKemId, HpkeKdfId, HpkeAeadId)' {PK11_HPKE_ValidateParameters@@NSS_3.58}
[A] 'function PK11SymKey* PK11_ImportDataKey(PK11SlotInfo*, CK_MECHANISM_TYPE, PK11Origin, CK_ATTRIBUTE_TYPE, SECItem*, void*)' {PK11_ImportDataKey@@NSS_3.58}
......@@ -12,7 +12,7 @@ if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then
fi
# Build.
nss/build.sh -g -v --enable-libpkix "$@"
nss/build.sh -g -v --enable-libpkix -Denable_draft_hpke=1 "$@"
# Package.
if [[ $(uname) = "Darwin" ]]; then
......
......@@ -38,7 +38,7 @@ if [[ -f nss/nspr.patch && "$ALLOW_NSPR_PATCH" == "1" ]]; then
fi
# Build with gyp.
./nss/build.sh -g -v --enable-libpkix "$@"
./nss/build.sh -g -v --enable-libpkix -Denable_draft_hpke=1 "$@"
# Package.
7z a public/build/dist.7z dist
......@@ -132,6 +132,7 @@
'mozpkix_only%': 0,
'coverage%': 0,
'softfp_cflags%': '',
'enable_draft_hpke%': 0,
},
'target_defaults': {
# Settings specific to targets should go here.
......@@ -568,6 +569,11 @@
'NSS_DISABLE_DBM',
],
}],
[ 'enable_draft_hpke==1', {
'defines': [
'NSS_ENABLE_DRAFT_HPKE',
],
}],
[ 'disable_libpkix==1', {
'defines': [
'NSS_DISABLE_LIBPKIX',
......
......@@ -195,6 +195,10 @@ ifdef NSS_PKIX_NO_LDAP
DEFINES += -DNSS_PKIX_NO_LDAP
endif
ifdef NSS_ENABLE_DRAFT_HPKE
DEFINES += -DNSS_ENABLE_DRAFT_HPKE
endif
# FIPS support requires startup tests to be executed at load time of shared modules.
# For performance reasons, these tests are disabled by default.
# When compiling binaries that must support FIPS mode,
......
......@@ -11,6 +11,7 @@
#include "cert.h"
#include "keyhi.h"
#include "p12.h"
#include "pk11hpke.h"
#include "pk11pqg.h"
#include "pk11pub.h"
#include "pkcs11uri.h"
......@@ -27,6 +28,9 @@ struct ScopedDelete {
void operator()(CERTSubjectPublicKeyInfo* spki) {
SECKEY_DestroySubjectPublicKeyInfo(spki);
}
void operator()(HpkeContext* context) {
PK11_HPKE_DestroyContext(context, true);
}
void operator()(PK11Context* context) { PK11_DestroyContext(context, true); }
void operator()(PK11GenericObject* obj) { PK11_DestroyGenericObject(obj); }
void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); }
......@@ -70,6 +74,7 @@ SCOPED(CERTCertificateList);
SCOPED(CERTDistNames);
SCOPED(CERTName);
SCOPED(CERTSubjectPublicKeyInfo);
SCOPED(HpkeContext);
SCOPED(PK11Context);
SCOPED(PK11GenericObject);
SCOPED(PK11SlotInfo);
......
This diff is collapsed.
......@@ -21,6 +21,7 @@ CPPSRCS = \
pk11_encrypt_derive_unittest.cc \
pk11_export_unittest.cc \
pk11_find_certs_unittest.cc \
pk11_hpke_unittest.cc \
pk11_hkdf_unittest.cc \
pk11_import_unittest.cc \
pk11_kbkdf.cc \
......
......@@ -27,6 +27,7 @@
'pk11_encrypt_derive_unittest.cc',
'pk11_find_certs_unittest.cc',
'pk11_hkdf_unittest.cc',
'pk11_hpke_unittest.cc',
'pk11_import_unittest.cc',
'pk11_kbkdf.cc',
'pk11_keygen.cc',
......
This diff is collapsed.
......@@ -522,7 +522,7 @@ VFY_EndWithSignature;
;+NSS_3.3.1 { # NSS 3.3.1 release
;+ global:
;+#
;+# The following symbols are exported only to make libsmime3.so work.
;+# The following symbols are exported only to make libsmime3.so work.
;+# These are still private!!!
;+#
PK11_CreatePBEParams;
......@@ -1189,6 +1189,17 @@ PK11_FindEncodedCertInSlot;
;+};
;+NSS_3.58 { # NSS 3.58 release
;+ global:
PK11_HPKE_DestroyContext;
PK11_HPKE_Deserialize;
PK11_HPKE_ExportSecret;
PK11_HPKE_GetEncapPubKey;
PK11_HPKE_NewContext;
PK11_HPKE_Open;
PK11_HPKE_Seal;
PK11_HPKE_Serialize;
PK11_HPKE_SetupS;
PK11_HPKE_SetupR;
PK11_HPKE_ValidateParameters;
PK11_ImportDataKey;
;+ local:
;+ *;
......
......@@ -13,6 +13,7 @@
{
'files': [
'pk11func.h',
'pk11hpke.h',
'pk11pqg.h',
'pk11priv.h',
'pk11pub.h',
......
#
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
......@@ -9,6 +9,7 @@ EXPORTS = \
secmodt.h \
secpkcs5.h \
pk11func.h \
pk11hpke.h \
pk11pub.h \
pk11priv.h \
pk11sdr.h \
......@@ -30,6 +31,7 @@ CSRCS = \
pk11cert.c \
pk11cxt.c \
pk11err.c \
pk11hpke.c \
pk11kea.c \
pk11list.c \
pk11load.c \
......
This diff is collapsed.
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _PK11_HPKE_H_
#define _PK11_HPKE_H_ 1
#include "blapit.h"
#include "seccomon.h"
#ifdef NSS_ENABLE_DRAFT_HPKE
#define HPKE_DRAFT_VERSION 5
#define CLEANUP \
PORT_Assert(rv == SECSuccess); \
cleanup
/* Error code must already be set. */
#define CHECK_RV(rv) \
if ((rv) != SECSuccess) { \
goto cleanup; \
}
/* Error code must already be set. */
#define CHECK_FAIL(cond) \
if ((cond)) { \
rv = SECFailure; \
goto cleanup; \
}
#define CHECK_FAIL_ERR(cond, err) \
if ((cond)) { \
PORT_SetError((err)); \
rv = SECFailure; \
goto cleanup; \
}
#endif /* NSS_ENABLE_DRAFT_HPKE */
typedef enum {
HpkeModeBase = 0,
HpkeModePsk = 1,
} HpkeModeId;
/* https://tools.ietf.org/html/draft-irtf-cfrg-hpke-05#section-7.1 */
typedef enum {
HpkeDhKemX25519Sha256 = 0x20,
} HpkeKemId;
typedef enum {
HpkeKdfHkdfSha256 = 1,
} HpkeKdfId;
typedef enum {
HpkeAeadAes128Gcm = 1,
HpkeAeadChaCha20Poly1305 = 3,
} HpkeAeadId;
typedef struct hpkeKemParamsStr {
HpkeKemId id;
unsigned int Nsk;
unsigned int Nsecret;
unsigned int Npk;
SECOidTag oidTag;
CK_MECHANISM_TYPE hashMech;
} hpkeKemParams;
typedef struct hpkeKdfParamsStr {
HpkeKdfId id;
unsigned int Nh;
CK_MECHANISM_TYPE mech;
} hpkeKdfParams;
typedef struct hpkeAeadParamsStr {
HpkeAeadId id;
unsigned int Nk;
unsigned int Nn;
unsigned int tagLen;
CK_MECHANISM_TYPE mech;
} hpkeAeadParams;
typedef struct HpkeContextStr HpkeContext;
#endif /* _PK11_HPKE_H_ */
......@@ -9,6 +9,7 @@
#include "secdert.h"
#include "keythi.h"
#include "certt.h"
#include "pk11hpke.h"
#include "pkcs11t.h"
#include "secmodt.h"
#include "seccomon.h"
......@@ -714,6 +715,36 @@ CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot,
CK_ATTRIBUTE_TYPE type,
PRBool haslock /* must be set to PR_FALSE */);
/**********************************************************************
* Hybrid Public Key Encryption (draft-05)
**********************************************************************/
/*
* NOTE: All HPKE functions will fail with SEC_ERROR_INVALID_ALGORITHM
* unless NSS is compiled with NSS_ENABLE_DRAFT_HPKE while spec (and
* implementation) is in draft. The eventual RFC number is an input to
* the key schedule, so applications opting into this MUST be prepared for
* outputs to change when the implementation is updated or finalized. */
/* Some of the various HPKE arguments would ideally be const, but the
* underlying PK11 functions take them as non-const. To avoid lying to
* the application with a cast, this idiosyncrasy is exposed. */
SECStatus PK11_HPKE_ValidateParameters(HpkeKemId kemId, HpkeKdfId kdfId, HpkeAeadId aeadId);
HpkeContext *PK11_HPKE_NewContext(HpkeKemId kemId, HpkeKdfId kdfId, HpkeAeadId aeadId,
PK11SymKey *psk, const SECItem *pskId);
SECStatus PK11_HPKE_Deserialize(const HpkeContext *cx, const PRUint8 *enc,
unsigned int encLen, SECKEYPublicKey **outPubKey);
void PK11_HPKE_DestroyContext(HpkeContext *cx, PRBool freeit);
const SECItem *PK11_HPKE_GetEncapPubKey(const HpkeContext *cx);
SECStatus PK11_HPKE_ExportSecret(const HpkeContext *cx, const SECItem *info, unsigned int L,
PK11SymKey **outKey);
SECStatus PK11_HPKE_Open(HpkeContext *cx, const SECItem *aad, const SECItem *ct, SECItem **outPt);
SECStatus PK11_HPKE_Seal(HpkeContext *cx, const SECItem *aad, const SECItem *pt, SECItem **outCt);
SECStatus PK11_HPKE_Serialize(const SECKEYPublicKey *pk, PRUint8 *buf, unsigned int *len, unsigned int maxLen);
SECStatus PK11_HPKE_SetupS(HpkeContext *cx, const SECKEYPublicKey *pkE, SECKEYPrivateKey *skE,
SECKEYPublicKey *pkR, const SECItem *info);
SECStatus PK11_HPKE_SetupR(HpkeContext *cx, const SECKEYPublicKey *pkR, SECKEYPrivateKey *skR,
const SECItem *enc, const SECItem *info);
/**********************************************************************
* Sign/Verify
**********************************************************************/
......
......@@ -37,6 +37,7 @@
'pk11cert.c',
'pk11cxt.c',
'pk11err.c',
'pk11hpke.c',
'pk11kea.c',
'pk11list.c',
'pk11load.c',
......
......@@ -549,3 +549,6 @@ ER3(SEC_ERROR_LEGACY_DATABASE, (SEC_ERROR_BASE + 177),
ER3(SEC_ERROR_APPLICATION_CALLBACK_ERROR, (SEC_ERROR_BASE + 178),
"The certificate was rejected by extra checks in the application.")
ER3(SEC_ERROR_INVALID_STATE, (SEC_ERROR_BASE + 179),
"The attempted operation is invalid for the current state.")
......@@ -210,6 +210,8 @@ typedef enum {
SEC_ERROR_APPLICATION_CALLBACK_ERROR = (SEC_ERROR_BASE + 178),
SEC_ERROR_INVALID_STATE = (SEC_ERROR_BASE + 179),
/* Add new error codes above here. */
SEC_ERROR_END_OF_LIST
} SECErrorCodes;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment