]> git.ipfire.org Git - thirdparty/strongswan.git/blobdiff - scripts/crypt_burn.c
crypt-burn: Add sanity check for buffer length
[thirdparty/strongswan.git] / scripts / crypt_burn.c
index bcd07c96837723fa0e1e785503c836871f9cea14..bf338f0b4e000c38def0a6f2497caf35d395b47f 100644 (file)
@@ -16,9 +16,9 @@
 #include <stdio.h>
 #include <library.h>
 
-static int burn_crypter(const proposal_token_t *token, u_int limit)
+static int burn_crypter(const proposal_token_t *token, u_int limit, u_int len)
 {
-       chunk_t iv,  data;
+       chunk_t iv, key, data;
        crypter_t *crypter;
        int i = 0;
        bool ok;
@@ -34,10 +34,12 @@ static int burn_crypter(const proposal_token_t *token, u_int limit)
 
        iv = chunk_alloc(crypter->get_iv_size(crypter));
        memset(iv.ptr, 0xFF, iv.len);
-       data = chunk_alloc(round_up(1024, crypter->get_block_size(crypter)));
+       data = chunk_alloc(round_up(len, crypter->get_block_size(crypter)));
        memset(data.ptr, 0xDD, data.len);
+       key = chunk_alloc(crypter->get_key_size(crypter));
+       memset(key.ptr, 0xAA, key.len);
 
-       ok = TRUE;
+       ok = crypter->set_key(crypter, key);
        while (ok)
        {
                if (!crypter->encrypt(crypter, data, iv, NULL))
@@ -61,13 +63,14 @@ static int burn_crypter(const proposal_token_t *token, u_int limit)
 
        free(iv.ptr);
        free(data.ptr);
+       free(key.ptr);
 
        return ok;
 }
 
-static bool burn_aead(const proposal_token_t *token, u_int limit)
+static bool burn_aead(const proposal_token_t *token, u_int limit, u_int len)
 {
-       chunk_t iv, data, dataicv, assoc;
+       chunk_t iv, key, data, dataicv, assoc;
        aead_t *aead;
        int i = 0;
        bool ok;
@@ -83,14 +86,16 @@ static bool burn_aead(const proposal_token_t *token, u_int limit)
 
        iv = chunk_alloc(aead->get_iv_size(aead));
        memset(iv.ptr, 0xFF, iv.len);
-       dataicv = chunk_alloc(round_up(1024, aead->get_block_size(aead)) +
+       dataicv = chunk_alloc(round_up(len, aead->get_block_size(aead)) +
                                                  aead->get_icv_size(aead));
        data = chunk_create(dataicv.ptr, dataicv.len - aead->get_icv_size(aead));
        memset(data.ptr, 0xDD, data.len);
        assoc = chunk_alloc(13);
        memset(assoc.ptr, 0xCC, assoc.len);
+       key = chunk_alloc(aead->get_key_size(aead));
+       memset(key.ptr, 0xAA, key.len);
 
-       ok = TRUE;
+       ok = aead->set_key(aead, key);
        while (ok)
        {
                if (!aead->encrypt(aead, data, assoc, iv, NULL))
@@ -114,6 +119,58 @@ static bool burn_aead(const proposal_token_t *token, u_int limit)
 
        free(iv.ptr);
        free(data.ptr);
+       free(key.ptr);
+       free(assoc.ptr);
+
+       return ok;
+}
+
+static int burn_signer(const proposal_token_t *token, u_int limit, u_int len)
+{
+       chunk_t  key, data, sig;
+       signer_t *signer;
+       int i = 0;
+       bool ok;
+
+       signer = lib->crypto->create_signer(lib->crypto, token->algorithm);
+       if (!signer)
+       {
+               fprintf(stderr, "%N not supported\n",
+                               integrity_algorithm_names, token->algorithm);
+               return FALSE;
+       }
+
+       data = chunk_alloc(len);
+       memset(data.ptr, 0xDD, data.len);
+       key = chunk_alloc(signer->get_key_size(signer));
+       memset(key.ptr, 0xAA, key.len);
+       sig = chunk_alloc(signer->get_block_size(signer));
+
+       ok = signer->set_key(signer, key);
+       while (ok)
+       {
+               if (!signer->get_signature(signer, data, sig.ptr))
+               {
+                       fprintf(stderr, "creating signature failed!\n");
+                       ok = FALSE;
+                       break;
+               }
+               if (!signer->verify_signature(signer, data, sig))
+               {
+                       fprintf(stderr, "verifying signature failed!\n");
+                       ok = FALSE;
+                       break;
+               }
+               if (limit && ++i == limit)
+               {
+                       break;
+               }
+       }
+       signer->destroy(signer);
+
+       free(data.ptr);
+       free(key.ptr);
+       free(sig.ptr);
 
        return ok;
 }
@@ -121,7 +178,7 @@ static bool burn_aead(const proposal_token_t *token, u_int limit)
 int main(int argc, char *argv[])
 {
        const proposal_token_t *token;
-       int limit = 0;
+       u_int limit = 0, len = 1024;
        bool ok;
 
        library_init(NULL, "crypt_burn");
@@ -132,12 +189,22 @@ int main(int argc, char *argv[])
 
        if (argc < 2)
        {
-               fprintf(stderr, "usage: %s <algorithm>!\n", argv[0]);
+               fprintf(stderr, "usage: %s <algorithm> [buflen=%u] [rounds=%u]\n",
+                               argv[0], len, limit);
                return 1;
        }
        if (argc > 2)
        {
-               limit = atoi(argv[2]);
+               len = atoi(argv[2]);
+               if (len > (2^30))
+               {
+                       fprintf(stderr, "buffer too large (1 GiB limit)\n");
+                       return 1;
+               }
+       }
+       if (argc > 3)
+       {
+               limit = atoi(argv[3]);
        }
 
        token = lib->proposal->get_token(lib->proposal, argv[1]);
@@ -152,13 +219,16 @@ int main(int argc, char *argv[])
                case ENCRYPTION_ALGORITHM:
                        if (encryption_algorithm_is_aead(token->algorithm))
                        {
-                               ok = burn_aead(token, limit);
+                               ok = burn_aead(token, limit, len);
                        }
                        else
                        {
-                               ok = burn_crypter(token, limit);
+                               ok = burn_crypter(token, limit, len);
                        }
                        break;
+               case INTEGRITY_ALGORITHM:
+                       ok = burn_signer(token, limit, len);
+                       break;
                default:
                        fprintf(stderr, "'%s' is not a crypter/aead algorithm!\n", argv[1]);
                        ok = FALSE;