@ -52,6 +52,7 @@ typedef struct {
// hash_c implements the H_c operation in PMBTokens. It returns one on success
// hash_c implements the H_c operation in PMBTokens. It returns one on success
// and zero on error.
// and zero on error.
hash_c_func_t hash_c ;
hash_c_func_t hash_c ;
int prefix_point : 1 ;
} PMBTOKEN_METHOD ;
} PMBTOKEN_METHOD ;
static const uint8_t kDefaultAdditionalData [ 32 ] = { 0 } ;
static const uint8_t kDefaultAdditionalData [ 32 ] = { 0 } ;
@ -59,7 +60,7 @@ static const uint8_t kDefaultAdditionalData[32] = {0};
static int pmbtoken_init_method ( PMBTOKEN_METHOD * method , int curve_nid ,
static int pmbtoken_init_method ( PMBTOKEN_METHOD * method , int curve_nid ,
const uint8_t * h_bytes , size_t h_len ,
const uint8_t * h_bytes , size_t h_len ,
hash_t_func_t hash_t , hash_s_func_t hash_s ,
hash_t_func_t hash_t , hash_s_func_t hash_s ,
hash_c_func_t hash_c ) {
hash_c_func_t hash_c , int prefix_point ) {
method - > group = EC_GROUP_new_by_curve_name ( curve_nid ) ;
method - > group = EC_GROUP_new_by_curve_name ( curve_nid ) ;
if ( method - > group = = NULL ) {
if ( method - > group = = NULL ) {
return 0 ;
return 0 ;
@ -68,6 +69,7 @@ static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid,
method - > hash_t = hash_t ;
method - > hash_t = hash_t ;
method - > hash_s = hash_s ;
method - > hash_s = hash_s ;
method - > hash_c = hash_c ;
method - > hash_c = hash_c ;
method - > prefix_point = prefix_point ;
EC_AFFINE h ;
EC_AFFINE h ;
if ( ! ec_point_from_uncompressed ( method - > group , & h , h_bytes , h_len ) ) {
if ( ! ec_point_from_uncompressed ( method - > group , & h , h_bytes , h_len ) ) {
@ -113,11 +115,40 @@ static int point_to_cbb(CBB *out, const EC_GROUP *group,
len ) = = len ;
len ) = = len ;
}
}
static int cbb_add_prefixed_point ( CBB * out , const EC_GROUP * group ,
const EC_AFFINE * point , int prefix_point ) {
if ( prefix_point ) {
CBB child ;
if ( ! CBB_add_u16_length_prefixed ( out , & child ) | |
! point_to_cbb ( & child , group , point ) | |
! CBB_flush ( out ) ) {
return 0 ;
}
} else {
if ( ! point_to_cbb ( out , group , point ) | |
! CBB_flush ( out ) ) {
return 0 ;
}
}
return 1 ;
}
static int cbs_get_prefixed_point ( CBS * cbs , const EC_GROUP * group ,
static int cbs_get_prefixed_point ( CBS * cbs , const EC_GROUP * group ,
EC_AFFINE * out ) {
EC_AFFINE * out , int prefix_point ) {
CBS child ;
CBS child ;
if ( ! CBS_get_u16_length_prefixed ( cbs , & child ) | |
if ( prefix_point ) {
! ec_point_from_uncompressed ( group , out , CBS_data ( & child ) ,
if ( ! CBS_get_u16_length_prefixed ( cbs , & child ) ) {
return 0 ;
}
} else {
size_t plen = 1 + 2 * BN_num_bytes ( & group - > field ) ;
if ( ! CBS_get_bytes ( cbs , & child , plen ) ) {
return 0 ;
}
}
if ( ! ec_point_from_uncompressed ( group , out , CBS_data ( & child ) ,
CBS_len ( & child ) ) ) {
CBS_len ( & child ) ) ) {
return 0 ;
return 0 ;
}
}
@ -166,16 +197,12 @@ static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method,
return 0 ;
return 0 ;
}
}
// TODO(https://crbug.com/boringssl/331): When updating the key format, remove
if ( ! cbb_add_prefixed_point ( out_public , group , & pub_affine [ 0 ] ,
// the redundant length prefixes.
method - > prefix_point ) | |
CBB child ;
! cbb_add_prefixed_point ( out_public , group , & pub_affine [ 1 ] ,
if ( ! CBB_add_u16_length_prefixed ( out_public , & child ) | |
method - > prefix_point ) | |
! point_to_cbb ( & child , group , & pub_affine [ 0 ] ) | |
! cbb_add_prefixed_point ( out_public , group , & pub_affine [ 2 ] ,
! CBB_add_u16_length_prefixed ( out_public , & child ) | |
method - > prefix_point ) ) {
! point_to_cbb ( & child , group , & pub_affine [ 1 ] ) | |
! CBB_add_u16_length_prefixed ( out_public , & child ) | |
! point_to_cbb ( & child , group , & pub_affine [ 2 ] ) | |
! CBB_flush ( out_public ) ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_BUFFER_TOO_SMALL ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_BUFFER_TOO_SMALL ) ;
return 0 ;
return 0 ;
}
}
@ -186,13 +213,14 @@ static int pmbtoken_generate_key(const PMBTOKEN_METHOD *method,
static int pmbtoken_client_key_from_bytes ( const PMBTOKEN_METHOD * method ,
static int pmbtoken_client_key_from_bytes ( const PMBTOKEN_METHOD * method ,
PMBTOKEN_CLIENT_KEY * key ,
PMBTOKEN_CLIENT_KEY * key ,
const uint8_t * in , size_t len ) {
const uint8_t * in , size_t len ) {
// TODO(https://crbug.com/boringssl/331): When updating the key format, remove
// the redundant length prefixes.
CBS cbs ;
CBS cbs ;
CBS_init ( & cbs , in , len ) ;
CBS_init ( & cbs , in , len ) ;
if ( ! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pub0 ) | |
if ( ! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pub0 ,
! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pub1 ) | |
method - > prefix_point ) | |
! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pubs ) | |
! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pub1 ,
method - > prefix_point ) | |
! cbs_get_prefixed_point ( & cbs , method - > group , & key - > pubs ,
method - > prefix_point ) | |
CBS_len ( & cbs ) ! = 0 ) {
CBS_len ( & cbs ) ! = 0 ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
return 0 ;
return 0 ;
@ -282,12 +310,8 @@ static STACK_OF(PMBTOKEN_PRETOKEN) *
goto err ;
goto err ;
}
}
// TODO(https://crbug.com/boringssl/331): When updating the key format,
if ( ! cbb_add_prefixed_point ( cbb , group , & pretoken - > Tp ,
// remove the redundant length prefixes.
method - > prefix_point ) ) {
CBB child ;
if ( ! CBB_add_u16_length_prefixed ( cbb , & child ) | |
! point_to_cbb ( & child , group , & pretoken - > Tp ) | |
! CBB_flush ( cbb ) ) {
goto err ;
goto err ;
}
}
}
}
@ -750,7 +774,7 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
for ( size_t i = 0 ; i < num_to_issue ; i + + ) {
for ( size_t i = 0 ; i < num_to_issue ; i + + ) {
EC_AFFINE Tp_affine ;
EC_AFFINE Tp_affine ;
EC_RAW_POINT Tp ;
EC_RAW_POINT Tp ;
if ( ! cbs_get_prefixed_point ( cbs , group , & Tp_affine ) ) {
if ( ! cbs_get_prefixed_point ( cbs , group , & Tp_affine , method - > prefix_point ) ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
goto err ;
goto err ;
}
}
@ -766,7 +790,6 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
// The |jacobians| and |affines| contain Sp, Wp, and Wsp.
// The |jacobians| and |affines| contain Sp, Wp, and Wsp.
EC_RAW_POINT jacobians [ 3 ] ;
EC_RAW_POINT jacobians [ 3 ] ;
EC_AFFINE affines [ 3 ] ;
EC_AFFINE affines [ 3 ] ;
CBB child ;
if ( ! method - > hash_s ( group , & jacobians [ 0 ] , & Tp_affine , s ) | |
if ( ! method - > hash_s ( group , & jacobians [ 0 ] , & Tp_affine , s ) | |
! ec_point_mul_scalar_batch ( group , & jacobians [ 1 ] , & Tp , & xb ,
! ec_point_mul_scalar_batch ( group , & jacobians [ 1 ] , & Tp , & xb ,
& jacobians [ 0 ] , & yb , NULL , NULL ) | |
& jacobians [ 0 ] , & yb , NULL , NULL ) | |
@ -774,12 +797,8 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
& jacobians [ 0 ] , & key - > ys , NULL , NULL ) | |
& jacobians [ 0 ] , & key - > ys , NULL , NULL ) | |
! ec_jacobian_to_affine_batch ( group , affines , jacobians , 3 ) | |
! ec_jacobian_to_affine_batch ( group , affines , jacobians , 3 ) | |
! CBB_add_bytes ( cbb , s , PMBTOKEN_NONCE_SIZE ) | |
! CBB_add_bytes ( cbb , s , PMBTOKEN_NONCE_SIZE ) | |
// TODO(https://crbug.com/boringssl/331): When updating the key format,
! cbb_add_prefixed_point ( cbb , group , & affines [ 1 ] , method - > prefix_point ) | |
// remove the redundant length prefixes.
! cbb_add_prefixed_point ( cbb , group , & affines [ 2 ] , method - > prefix_point ) ) {
! CBB_add_u16_length_prefixed ( cbb , & child ) | |
! point_to_cbb ( & child , group , & affines [ 1 ] ) | |
! CBB_add_u16_length_prefixed ( cbb , & child ) | |
! point_to_cbb ( & child , group , & affines [ 2 ] ) ) {
goto err ;
goto err ;
}
}
@ -835,7 +854,11 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
// Skip over any unused requests.
// Skip over any unused requests.
size_t point_len = 1 + 2 * BN_num_bytes ( & group - > field ) ;
size_t point_len = 1 + 2 * BN_num_bytes ( & group - > field ) ;
if ( ! CBS_skip ( cbs , ( 2 + point_len ) * ( num_requested - num_to_issue ) ) ) {
size_t token_len = point_len ;
if ( method - > prefix_point ) {
token_len + = 2 ;
}
if ( ! CBS_skip ( cbs , token_len * ( num_requested - num_to_issue ) ) ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
goto err ;
goto err ;
}
}
@ -902,8 +925,9 @@ static STACK_OF(TRUST_TOKEN) *
uint8_t s [ PMBTOKEN_NONCE_SIZE ] ;
uint8_t s [ PMBTOKEN_NONCE_SIZE ] ;
EC_AFFINE Wp_affine , Wsp_affine ;
EC_AFFINE Wp_affine , Wsp_affine ;
if ( ! CBS_copy_bytes ( cbs , s , PMBTOKEN_NONCE_SIZE ) | |
if ( ! CBS_copy_bytes ( cbs , s , PMBTOKEN_NONCE_SIZE ) | |
! cbs_get_prefixed_point ( cbs , group , & Wp_affine ) | |
! cbs_get_prefixed_point ( cbs , group , & Wp_affine , method - > prefix_point ) | |
! cbs_get_prefixed_point ( cbs , group , & Wsp_affine ) ) {
! cbs_get_prefixed_point ( cbs , group , & Wsp_affine ,
method - > prefix_point ) ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_DECODE_FAILURE ) ;
goto err ;
goto err ;
}
}
@ -937,19 +961,17 @@ static STACK_OF(TRUST_TOKEN) *
// Serialize the token. Include |key_id| to avoid an extra copy in the layer
// Serialize the token. Include |key_id| to avoid an extra copy in the layer
// above.
// above.
CBB token_cbb , child ;
CBB token_cbb ;
size_t point_len = 1 + 2 * BN_num_bytes ( & group - > field ) ;
size_t point_len = 1 + 2 * BN_num_bytes ( & group - > field ) ;
if ( ! CBB_init ( & token_cbb , 4 + PMBTOKEN_NONCE_SIZE + 3 * ( 2 + point_len ) ) | |
if ( ! CBB_init ( & token_cbb , 4 + PMBTOKEN_NONCE_SIZE + 3 * ( 2 + point_len ) ) | |
! CBB_add_u32 ( & token_cbb , key_id ) | |
! CBB_add_u32 ( & token_cbb , key_id ) | |
! CBB_add_bytes ( & token_cbb , pretoken - > t , PMBTOKEN_NONCE_SIZE ) | |
! CBB_add_bytes ( & token_cbb , pretoken - > t , PMBTOKEN_NONCE_SIZE ) | |
// TODO(https://crbug.com/boringssl/331): When updating the key format,
! cbb_add_prefixed_point ( & token_cbb , group , & affines [ 0 ] ,
// remove the redundant length prefixes.
method - > prefix_point ) | |
! CBB_add_u16_length_prefixed ( & token_cbb , & child ) | |
! cbb_add_prefixed_point ( & token_cbb , group , & affines [ 1 ] ,
! point_to_cbb ( & child , group , & affines [ 0 ] ) | |
method - > prefix_point ) | |
! CBB_add_u16_length_prefixed ( & token_cbb , & child ) | |
! cbb_add_prefixed_point ( & token_cbb , group , & affines [ 2 ] ,
! point_to_cbb ( & child , group , & affines [ 1 ] ) | |
method - > prefix_point ) | |
! CBB_add_u16_length_prefixed ( & token_cbb , & child ) | |
! point_to_cbb ( & child , group , & affines [ 2 ] ) | |
! CBB_flush ( & token_cbb ) ) {
! CBB_flush ( & token_cbb ) ) {
CBB_cleanup ( & token_cbb ) ;
CBB_cleanup ( & token_cbb ) ;
goto err ;
goto err ;
@ -1021,9 +1043,9 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method,
CBS_init ( & cbs , token , token_len ) ;
CBS_init ( & cbs , token , token_len ) ;
EC_AFFINE S , W , Ws ;
EC_AFFINE S , W , Ws ;
if ( ! CBS_copy_bytes ( & cbs , out_nonce , PMBTOKEN_NONCE_SIZE ) | |
if ( ! CBS_copy_bytes ( & cbs , out_nonce , PMBTOKEN_NONCE_SIZE ) | |
! cbs_get_prefixed_point ( & cbs , group , & S ) | |
! cbs_get_prefixed_point ( & cbs , group , & S , method - > prefix_point ) | |
! cbs_get_prefixed_point ( & cbs , group , & W ) | |
! cbs_get_prefixed_point ( & cbs , group , & W , method - > prefix_point ) | |
! cbs_get_prefixed_point ( & cbs , group , & Ws ) | |
! cbs_get_prefixed_point ( & cbs , group , & Ws , method - > prefix_point ) | |
CBS_len ( & cbs ) ! = 0 ) {
CBS_len ( & cbs ) ! = 0 ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_INVALID_TOKEN ) ;
OPENSSL_PUT_ERROR ( TRUST_TOKEN , TRUST_TOKEN_R_INVALID_TOKEN ) ;
return 0 ;
return 0 ;
@ -1140,7 +1162,7 @@ static void pmbtoken_exp1_init_method_impl(void) {
pmbtoken_exp1_ok =
pmbtoken_exp1_ok =
pmbtoken_init_method ( & pmbtoken_exp1_method , NID_secp384r1 , kH , sizeof ( kH ) ,
pmbtoken_init_method ( & pmbtoken_exp1_method , NID_secp384r1 , kH , sizeof ( kH ) ,
pmbtoken_exp1_hash_t , pmbtoken_exp1_hash_s ,
pmbtoken_exp1_hash_t , pmbtoken_exp1_hash_s ,
pmbtoken_exp1_hash_c ) ;
pmbtoken_exp1_hash_c , 1 ) ;
}
}
static int pmbtoken_exp1_init_method ( void ) {
static int pmbtoken_exp1_init_method ( void ) {
@ -1225,3 +1247,153 @@ int pmbtoken_exp1_get_h_for_testing(uint8_t out[97]) {
ec_point_to_bytes ( pmbtoken_exp1_method . group , & h ,
ec_point_to_bytes ( pmbtoken_exp1_method . group , & h ,
POINT_CONVERSION_UNCOMPRESSED , out , 97 ) = = 97 ;
POINT_CONVERSION_UNCOMPRESSED , out , 97 ) = = 97 ;
}
}
// PMBTokens experiment v2.
static int pmbtoken_exp2_hash_t ( const EC_GROUP * group , EC_RAW_POINT * out ,
const uint8_t t [ PMBTOKEN_NONCE_SIZE ] ) {
const uint8_t kHashTLabel [ ] = " PMBTokens Experiment V2 HashT " ;
return ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 (
group , out , kHashTLabel , sizeof ( kHashTLabel ) , t , PMBTOKEN_NONCE_SIZE ) ;
}
static int pmbtoken_exp2_hash_s ( const EC_GROUP * group , EC_RAW_POINT * out ,
const EC_AFFINE * t ,
const uint8_t s [ PMBTOKEN_NONCE_SIZE ] ) {
const uint8_t kHashSLabel [ ] = " PMBTokens Experiment V2 HashS " ;
int ret = 0 ;
CBB cbb ;
uint8_t * buf = NULL ;
size_t len ;
if ( ! CBB_init ( & cbb , 0 ) | |
! point_to_cbb ( & cbb , group , t ) | |
! CBB_add_bytes ( & cbb , s , PMBTOKEN_NONCE_SIZE ) | |
! CBB_finish ( & cbb , & buf , & len ) | |
! ec_hash_to_curve_p384_xmd_sha512_sswu_draft07 (
group , out , kHashSLabel , sizeof ( kHashSLabel ) , buf , len ) ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , ERR_R_MALLOC_FAILURE ) ;
goto err ;
}
ret = 1 ;
err :
OPENSSL_free ( buf ) ;
CBB_cleanup ( & cbb ) ;
return ret ;
}
static int pmbtoken_exp2_hash_c ( const EC_GROUP * group , EC_SCALAR * out ,
uint8_t * buf , size_t len ) {
const uint8_t kHashCLabel [ ] = " PMBTokens Experiment V2 HashC " ;
return ec_hash_to_scalar_p384_xmd_sha512_draft07 (
group , out , kHashCLabel , sizeof ( kHashCLabel ) , buf , len ) ;
}
static int pmbtoken_exp2_ok = 0 ;
static PMBTOKEN_METHOD pmbtoken_exp2_method ;
static CRYPTO_once_t pmbtoken_exp2_method_once = CRYPTO_ONCE_INIT ;
static void pmbtoken_exp2_init_method_impl ( void ) {
// This is the output of |ec_hash_to_scalar_p384_xmd_sha512_draft07| with DST
// "PMBTokens Experiment V2 HashH" and message "generator".
static const uint8_t kH [ ] = {
0x04 , 0xbc , 0x27 , 0x24 , 0x99 , 0xfa , 0xc9 , 0xa4 , 0x74 , 0x6f , 0xf9 ,
0x07 , 0x81 , 0x55 , 0xf8 , 0x1f , 0x6f , 0xda , 0x09 , 0xe7 , 0x8c , 0x5d ,
0x9e , 0x4e , 0x14 , 0x7c , 0x53 , 0x14 , 0xbc , 0x7e , 0x29 , 0x57 , 0x92 ,
0x17 , 0x94 , 0x6e , 0xd2 , 0xdf , 0xa5 , 0x31 , 0x1b , 0x4e , 0xb7 , 0xfc ,
0x93 , 0xe3 , 0x6e , 0x14 , 0x1f , 0x4f , 0x14 , 0xf3 , 0xe5 , 0x47 , 0x61 ,
0x1c , 0x2c , 0x72 , 0x25 , 0xf0 , 0x4a , 0x45 , 0x23 , 0x2d , 0x57 , 0x93 ,
0x0e , 0xb2 , 0x55 , 0xb8 , 0x57 , 0x25 , 0x4c , 0x1e , 0xdb , 0xfd , 0x58 ,
0x70 , 0x17 , 0x9a , 0xbb , 0x9e , 0x5e , 0x93 , 0x9e , 0x92 , 0xd3 , 0xe8 ,
0x25 , 0x62 , 0xbf , 0x59 , 0xb2 , 0xd2 , 0x3d , 0x71 , 0xff
} ;
pmbtoken_exp2_ok =
pmbtoken_init_method ( & pmbtoken_exp2_method , NID_secp384r1 , kH , sizeof ( kH ) ,
pmbtoken_exp2_hash_t , pmbtoken_exp2_hash_s ,
pmbtoken_exp2_hash_c , 0 ) ;
}
static int pmbtoken_exp2_init_method ( void ) {
CRYPTO_once ( & pmbtoken_exp2_method_once , pmbtoken_exp2_init_method_impl ) ;
if ( ! pmbtoken_exp2_ok ) {
OPENSSL_PUT_ERROR ( TRUST_TOKEN , ERR_R_INTERNAL_ERROR ) ;
return 0 ;
}
return 1 ;
}
int pmbtoken_exp2_generate_key ( CBB * out_private , CBB * out_public ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
return pmbtoken_generate_key ( & pmbtoken_exp2_method , out_private , out_public ) ;
}
int pmbtoken_exp2_client_key_from_bytes ( PMBTOKEN_CLIENT_KEY * key ,
const uint8_t * in , size_t len ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
return pmbtoken_client_key_from_bytes ( & pmbtoken_exp2_method , key , in , len ) ;
}
int pmbtoken_exp2_issuer_key_from_bytes ( PMBTOKEN_ISSUER_KEY * key ,
const uint8_t * in , size_t len ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
return pmbtoken_issuer_key_from_bytes ( & pmbtoken_exp2_method , key , in , len ) ;
}
STACK_OF ( PMBTOKEN_PRETOKEN ) * pmbtoken_exp2_blind ( CBB * cbb , size_t count ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return NULL ;
}
return pmbtoken_blind ( & pmbtoken_exp2_method , cbb , count ) ;
}
int pmbtoken_exp2_sign ( const PMBTOKEN_ISSUER_KEY * key , CBB * cbb , CBS * cbs ,
size_t num_requested , size_t num_to_issue ,
uint8_t private_metadata ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
return pmbtoken_sign ( & pmbtoken_exp2_method , key , cbb , cbs , num_requested ,
num_to_issue , private_metadata ) ;
}
STACK_OF ( TRUST_TOKEN ) *
pmbtoken_exp2_unblind ( const PMBTOKEN_CLIENT_KEY * key ,
const STACK_OF ( PMBTOKEN_PRETOKEN ) * pretokens ,
CBS * cbs , size_t count , uint32_t key_id ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return NULL ;
}
return pmbtoken_unblind ( & pmbtoken_exp2_method , key , pretokens , cbs , count ,
key_id ) ;
}
int pmbtoken_exp2_read ( const PMBTOKEN_ISSUER_KEY * key ,
uint8_t out_nonce [ PMBTOKEN_NONCE_SIZE ] ,
uint8_t * out_private_metadata , const uint8_t * token ,
size_t token_len ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
return pmbtoken_read ( & pmbtoken_exp2_method , key , out_nonce ,
out_private_metadata , token , token_len ) ;
}
int pmbtoken_exp2_get_h_for_testing ( uint8_t out [ 97 ] ) {
if ( ! pmbtoken_exp2_init_method ( ) ) {
return 0 ;
}
EC_AFFINE h ;
return ec_jacobian_to_affine ( pmbtoken_exp2_method . group , & h ,
& pmbtoken_exp2_method . h ) & &
ec_point_to_bytes ( pmbtoken_exp2_method . group , & h ,
POINT_CONVERSION_UNCOMPRESSED , out , 97 ) = = 97 ;
}