Home | History | Annotate | Line # | Download | only in crypto_kx
      1 
      2 #include <stddef.h>
      3 
      4 #include "core.h"
      5 #include "crypto_generichash.h"
      6 #include "crypto_kx.h"
      7 #include "crypto_scalarmult.h"
      8 #include "private/common.h"
      9 #include "randombytes.h"
     10 #include "utils.h"
     11 
     12 int
     13 crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
     14                        unsigned char sk[crypto_kx_SECRETKEYBYTES],
     15                        const unsigned char seed[crypto_kx_SEEDBYTES])
     16 {
     17     crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
     18                        seed, crypto_kx_SEEDBYTES, NULL, 0);
     19     return crypto_scalarmult_base(pk, sk);
     20 }
     21 
     22 int
     23 crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
     24                   unsigned char sk[crypto_kx_SECRETKEYBYTES])
     25 {
     26     COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
     27     COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
     28 
     29     randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
     30     return crypto_scalarmult_base(pk, sk);
     31 }
     32 
     33 int
     34 crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
     35                               unsigned char tx[crypto_kx_SESSIONKEYBYTES],
     36                               const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
     37                               const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
     38                               const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
     39 {
     40     crypto_generichash_state h;
     41     unsigned char            q[crypto_scalarmult_BYTES];
     42     unsigned char            keys[2 * crypto_kx_SESSIONKEYBYTES];
     43     int                      i;
     44 
     45     if (rx == NULL) {
     46         rx = tx;
     47     }
     48     if (tx == NULL) {
     49         tx = rx;
     50     }
     51     if (rx == NULL) {
     52         sodium_misuse(); /* LCOV_EXCL_LINE */
     53     }
     54     if (crypto_scalarmult(q, client_sk, server_pk) != 0) {
     55         return -1;
     56     }
     57     COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
     58     crypto_generichash_init(&h, NULL, 0U, sizeof keys);
     59     crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
     60     sodium_memzero(q, sizeof q);
     61     crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
     62     crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
     63     crypto_generichash_final(&h, keys, sizeof keys);
     64     sodium_memzero(&h, sizeof h);
     65     for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
     66         rx[i] = keys[i];
     67         tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
     68     }
     69     sodium_memzero(keys, sizeof keys);
     70 
     71     return 0;
     72 }
     73 
     74 int
     75 crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
     76                               unsigned char tx[crypto_kx_SESSIONKEYBYTES],
     77                               const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
     78                               const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
     79                               const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
     80 {
     81     crypto_generichash_state h;
     82     unsigned char            q[crypto_scalarmult_BYTES];
     83     unsigned char            keys[2 * crypto_kx_SESSIONKEYBYTES];
     84     int                      i;
     85 
     86     if (rx == NULL) {
     87         rx = tx;
     88     }
     89     if (tx == NULL) {
     90         tx = rx;
     91     }
     92     if (rx == NULL) {
     93         sodium_misuse(); /* LCOV_EXCL_LINE */
     94     }
     95     if (crypto_scalarmult(q, server_sk, client_pk) != 0) {
     96         return -1;
     97     }
     98     COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
     99     crypto_generichash_init(&h, NULL, 0U, sizeof keys);
    100     crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
    101     sodium_memzero(q, sizeof q);
    102     crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
    103     crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
    104     crypto_generichash_final(&h, keys, sizeof keys);
    105     sodium_memzero(&h, sizeof h);
    106     for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
    107         tx[i] = keys[i];
    108         rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
    109     }
    110     sodium_memzero(keys, sizeof keys);
    111 
    112     return 0;
    113 }
    114 
    115 size_t
    116 crypto_kx_publickeybytes(void)
    117 {
    118     return crypto_kx_PUBLICKEYBYTES;
    119 }
    120 
    121 size_t
    122 crypto_kx_secretkeybytes(void)
    123 {
    124     return crypto_kx_SECRETKEYBYTES;
    125 }
    126 
    127 size_t
    128 crypto_kx_seedbytes(void)
    129 {
    130     return crypto_kx_SEEDBYTES;
    131 }
    132 
    133 size_t
    134 crypto_kx_sessionkeybytes(void)
    135 {
    136     return crypto_kx_SESSIONKEYBYTES;
    137 }
    138 
    139 const char *
    140 crypto_kx_primitive(void)
    141 {
    142     return crypto_kx_PRIMITIVE;
    143 }
    144