sodiumTest

Libsodium examples, client/server system
git clone https://noulin.net/git/sodiumTest.git
Log | Files | Refs | README

sel.c (5841B)


      1 #include "sel.h"
      2 
      3 // detect entropy quality
      4 #include <fcntl.h>
      5 #include <unistd.h>
      6 #include <sys/ioctl.h>
      7 #include <linux/random.h>
      8 
      9 #include <iso646.h> /* and or not defines */
     10 
     11 signKeyst identityKeys                  = {0};
     12 u8 remoteId[crypto_sign_PUBLICKEYBYTES] = {0};
     13 sessionKeyst sessionKeys                = {0};
     14 keyst keys                              = {0};
     15 
     16 int selInit(void) {
     17   // detect entropy quality
     18   int urandomfd;
     19   if ((urandomfd = open("/dev/urandom", O_RDONLY)) != -1) {
     20     int c;
     21     if (ioctl(urandomfd, RNDGETENTCNT, &c) == 0 && c < 160) {
     22       /* logN("This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n" */
     23       /*     "Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n" */
     24       /*     "On virtualized Linux environments, also consider using virtio-rng.\n" */
     25       /*     "The service will not start until enough entropy has been collected.\n", stderr); */
     26       close(urandomfd);
     27       return 0;
     28     }
     29   }
     30   close(urandomfd);
     31   if (sodium_init() == -1) {
     32     /* logC("Panic! libsodium couldn't be initialized; it is not safe to use"); */
     33     return 0;
     34   }
     35   return 1;
     36 }
     37 
     38 void newKeys(void) {
     39   crypto_box_keypair(keys.publicKey, keys.secretKey);
     40 }
     41 
     42 void newKeysBuf(keyst *keys) {
     43   crypto_box_keypair(keys->publicKey, keys->secretKey);
     44   /* logD("Public key"); */
     45   /* loghex(keys->publicKey, sizeof(keys->publicKey)); */
     46   /* put; */
     47   /* logD("Secret key"); */
     48   /* loghex(keys->secretKey, sizeof(keys->secretKey)); */
     49   /* put; */
     50 }
     51 
     52 void newSignKeys(void) {
     53 	crypto_sign_keypair(identityKeys.publicKey, identityKeys.secretKey);
     54 }
     55 
     56 void newSignKeysBuf(signKeyst *keys) {
     57 	crypto_sign_keypair(keys->publicKey, keys->secretKey);
     58 }
     59 
     60 // return ciphertext (encrypted message) length
     61 int selPublicEncrypt(u8 *ciphertext/*result*/, size_t csize, const u8 *msg, size_t mlen, keyst *keys) {
     62   // csize is ciphertext buffer size
     63   // check is there is enough space in ciphertext
     64   if (csize < mlen + crypto_box_MACBYTES) return 0;
     65   if (crypto_box_easy(ciphertext, msg, mlen, keys->nonce, keys->remotePublicKey, keys->secretKey) != 0) return 0;
     66   return mlen + crypto_box_MACBYTES;
     67 }
     68 
     69 // return message length
     70 int selPublicDecrypt(u8 *msg/*result*/, size_t msize, const u8 *ciphertext, size_t clen, keyst *keys) {
     71   // msize is message buffer size
     72   // check ciphertext has minimal length, the message has to be at least one byte
     73   // check is there is enough space in message buffer
     74   if (clen <= crypto_box_MACBYTES or msize < clen - crypto_box_MACBYTES) return 0;
     75   if (crypto_box_open_easy(msg, ciphertext, clen, keys->nonce, keys->remotePublicKey, keys->secretKey) != 0) return 0;
     76   return clen - crypto_box_MACBYTES;
     77 }
     78 
     79 int computeSharedKeys(int clientOrServer) {
     80   switch (clientOrServer) {
     81     case CLIENT_SESSION_KEYS:
     82       if (crypto_kx_client_session_keys(sessionKeys.rx, sessionKeys.tx, keys.publicKey, keys.secretKey, keys.remotePublicKey) != 0) {
     83         // Suspicious server public key, bail out
     84         return 0;
     85       }
     86       break;
     87     case SERVER_SESSION_KEYS:
     88       if (crypto_kx_server_session_keys(sessionKeys.rx, sessionKeys.tx, keys.publicKey, keys.secretKey, keys.remotePublicKey) != 0) {
     89         // Suspicious server public key, bail out
     90         return 0;
     91       }
     92       break;
     93     default:
     94       return 0;
     95   }
     96   return 1;
     97 }
     98 
     99 int computeSharedKeysBuf(int clientOrServer, sessionKeyst *sessionKeys, keyst *keys) {
    100   switch (clientOrServer) {
    101     case CLIENT_SESSION_KEYS:
    102       if (crypto_kx_client_session_keys(sessionKeys->rx, sessionKeys->tx, keys->publicKey, keys->secretKey, keys->remotePublicKey) != 0) {
    103         // Suspicious server public key, bail out
    104         return 0;
    105       }
    106       break;
    107     case SERVER_SESSION_KEYS:
    108       if (crypto_kx_server_session_keys(sessionKeys->rx, sessionKeys->tx, keys->publicKey, keys->secretKey, keys->remotePublicKey) != 0) {
    109         // Suspicious server public key, bail out
    110         return 0;
    111       }
    112       break;
    113     default:
    114       return 0;
    115   }
    116   return 1;
    117 }
    118 
    119 int selEncrypt(u8 *ciphertext/*result*/, size_t csize, const u8 *msg, size_t mlen) {
    120   // csize is ciphertext buffer size
    121   // check is there is enough space in ciphertext
    122   if (csize < mlen + crypto_secretbox_MACBYTES) return 0;
    123   if (crypto_secretbox_easy(ciphertext, msg, mlen, sessionKeys.nonce, sessionKeys.tx) != 0) return 0;
    124   return mlen + crypto_secretbox_MACBYTES;
    125 }
    126 
    127 int selEncryptBuf(u8 *ciphertext/*result*/, size_t csize, const u8 *msg, size_t mlen, const u8 *nonce, const u8 *k) {
    128   // csize is ciphertext buffer size
    129   // check is there is enough space in ciphertext
    130   if (csize < mlen + crypto_secretbox_MACBYTES) return 0;
    131   if (crypto_secretbox_easy(ciphertext, msg, mlen, nonce, k) != 0) return 0;
    132   return mlen + crypto_secretbox_MACBYTES;
    133 }
    134 
    135 int selDecrypt(u8 *msg/*result*/, size_t msize, const u8 *ciphertext, size_t clen) {
    136   // msize is message buffer size
    137   // check ciphertext has minimal length, the message has to be at least one byte
    138   // check is there is enough space in message buffer
    139   if (clen <= crypto_secretbox_MACBYTES or msize < clen - crypto_secretbox_MACBYTES) return 0;
    140 	if (crypto_secretbox_open_easy(msg, ciphertext, clen, sessionKeys.nonce, sessionKeys.rx) != 0) return 0;
    141   return clen - crypto_secretbox_MACBYTES;
    142 }
    143 
    144 int selDecryptBuf(u8 *msg/*result*/, size_t msize, const u8 *ciphertext, size_t clen, const u8 *nonce, const u8 *k) {
    145   // msize is message buffer size
    146   // check ciphertext has minimal length, the message has to be at least one byte
    147   // check is there is enough space in message buffer
    148   if (clen <= crypto_secretbox_MACBYTES or msize < clen - crypto_secretbox_MACBYTES) return 0;
    149 	if (crypto_secretbox_open_easy(msg, ciphertext, clen, nonce, k) != 0) return 0;
    150   return clen - crypto_secretbox_MACBYTES;
    151 }
    152 
    153 // vim: set expandtab ts=2 sw=2: