If we link with OpenSSL, use it for Chacha20-Poly1305 as well.
authorGuus Sliepen <guus@tinc-vpn.org>
Mon, 9 Aug 2021 19:55:09 +0000 (21:55 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 29 May 2022 15:48:46 +0000 (17:48 +0200)
src/sptps.c

index 7be8cd8..500bf83 100644 (file)
@@ -116,12 +116,26 @@ static bool cipher_init(uint8_t suite, void **ctx, const sptps_key_t *keys, bool
         const uint8_t *key = key_half ? keys->key1 : keys->key0;
 
        switch(suite) {
+#ifndef HAVE_OPENSSL
+
        case SPTPS_CHACHA_POLY1305:
                *ctx = chacha_poly1305_init();
                return ctx && chacha_poly1305_set_key(*ctx, key);
 
+#else
+
+       case SPTPS_CHACHA_POLY1305:
+               *ctx = EVP_CIPHER_CTX_new();
+
+               if(!ctx) {
+                       return false;
+               }
+
+               return EVP_EncryptInit_ex(*ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL)
+                      && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)
+                      && EVP_EncryptInit_ex(*ctx, NULL, NULL, key, key + 32);
+
        case SPTPS_AES256_GCM:
-#ifdef HAVE_OPENSSL
                *ctx = EVP_CIPHER_CTX_new();
 
                if(!ctx) {
@@ -129,7 +143,7 @@ static bool cipher_init(uint8_t suite, void **ctx, const sptps_key_t *keys, bool
                }
 
                return EVP_EncryptInit_ex(*ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)
-                      && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_AEAD_SET_IVLEN, 4, NULL)
+                      && EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)
                       && EVP_EncryptInit_ex(*ctx, NULL, NULL, key, key + 32);
 #endif
 
@@ -140,12 +154,16 @@ static bool cipher_init(uint8_t suite, void **ctx, const sptps_key_t *keys, bool
 
 static void cipher_exit(uint8_t suite, void *ctx) {
        switch(suite) {
+#ifndef HAVE_OPENSSL
+
        case SPTPS_CHACHA_POLY1305:
                chacha_poly1305_exit(ctx);
                break;
 
+#else
+
+       case SPTPS_CHACHA_POLY1305:
        case SPTPS_AES256_GCM:
-#ifdef HAVE_OPENSSL
                EVP_CIPHER_CTX_free(ctx);
                break;
 #endif
@@ -157,42 +175,47 @@ static void cipher_exit(uint8_t suite, void *ctx) {
 
 static bool cipher_encrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) {
        switch(suite) {
+#ifndef HAVE_OPENSSL
+
        case SPTPS_CHACHA_POLY1305:
                chacha_poly1305_encrypt(ctx, seqno, in, inlen, out, outlen);
                return true;
 
-       case SPTPS_AES256_GCM:
-#ifdef HAVE_OPENSSL
-               {
-                       if(!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, (uint8_t *)&seqno)) {
-                               return false;
-                       }
+#else
 
-                       int outlen1 = 0, outlen2 = 0;
+       case SPTPS_CHACHA_POLY1305:
+       case SPTPS_AES256_GCM: {
+               uint8_t nonce[12] = {seqno, seqno >> 8, seqno >> 16, seqno >> 24};
 
-                       if(!EVP_EncryptUpdate(ctx, out, &outlen1, in, (int)inlen)) {
-                               return false;
-                       }
+               if(!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce)) {
+                       return false;
+               }
 
-                       if(!EVP_EncryptFinal_ex(ctx, out + outlen1, &outlen2)) {
-                               return false;
-                       }
+               int outlen1 = 0, outlen2 = 0;
 
-                       outlen1 += outlen2;
+               if(!EVP_EncryptUpdate(ctx, out, &outlen1, in, (int)inlen)) {
+                       return false;
+               }
 
-                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, out + outlen1)) {
-                               return false;
-                       }
+               if(!EVP_EncryptFinal_ex(ctx, out + outlen1, &outlen2)) {
+                       return false;
+               }
 
-                       outlen1 += 16;
+               outlen1 += outlen2;
 
-                       if(outlen) {
-                               *outlen = outlen1;
-                       }
+               if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, out + outlen1)) {
+                       return false;
+               }
+
+               outlen1 += 16;
 
-                       return true;
+               if(outlen) {
+                       *outlen = outlen1;
                }
 
+               return true;
+       }
+
 #endif
 
        default:
@@ -202,43 +225,48 @@ static bool cipher_encrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8
 
 static bool cipher_decrypt(uint8_t suite, void *ctx, uint32_t seqno, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) {
        switch(suite) {
+#ifndef HAVE_OPENSSL
+
        case SPTPS_CHACHA_POLY1305:
                return chacha_poly1305_decrypt(ctx, seqno, in, inlen, out, outlen);
 
-       case SPTPS_AES256_GCM:
-#ifdef HAVE_OPENSSL
-               {
-                       if(inlen < 16) {
-                               return false;
-                       }
+#else
 
-                       inlen -= 16;
+       case SPTPS_CHACHA_POLY1305:
+       case SPTPS_AES256_GCM: {
+               if(inlen < 16) {
+                       return false;
+               }
 
-                       if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (uint8_t *)&seqno)) {
-                               return false;
-                       }
+               inlen -= 16;
 
-                       int outlen1 = 0, outlen2 = 0;
+               uint8_t nonce[12] = {seqno, seqno >> 8, seqno >> 16, seqno >> 24};
 
-                       if(!EVP_DecryptUpdate(ctx, out, &outlen1, in, (int)inlen)) {
-                               return false;
-                       }
+               if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce)) {
+                       return false;
+               }
 
-                       if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void *)(in + inlen))) {
-                               return false;
-                       }
+               int outlen1 = 0, outlen2 = 0;
 
-                       if(!EVP_DecryptFinal_ex(ctx, out + outlen1, &outlen2)) {
-                               return false;
-                       }
+               if(!EVP_DecryptUpdate(ctx, out, &outlen1, in, (int)inlen)) {
+                       return false;
+               }
 
-                       if(outlen) {
-                               *outlen = outlen1 + outlen2;
-                       }
+               if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void *)(in + inlen))) {
+                       return false;
+               }
+
+               if(!EVP_DecryptFinal_ex(ctx, out + outlen1, &outlen2)) {
+                       return false;
+               }
 
-                       return true;
+               if(outlen) {
+                       *outlen = outlen1 + outlen2;
                }
 
+               return true;
+       }
+
 #endif
 
        default: