Variable key length crypters use default key length if zero given
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_crypter.c
index a410eee..1cecec8 100644 (file)
@@ -41,79 +41,48 @@ struct private_openssl_crypter_t {
 };
 
 /**
- * Mapping from the algorithms defined in IKEv2 to
- * OpenSSL algorithm names and their key length
- */
-typedef struct {
-       /**
-        * Identifier specified in IKEv2
-        */
-       int ikev2_id;
-
-       /**
-        * Name of the algorithm, as used in OpenSSL
-        */
-       char *name;
-
-       /**
-        * Minimum valid key length in bytes
-        */
-       size_t key_size_min;
-
-       /**
-        * Maximum valid key length in bytes
-        */
-       size_t key_size_max;
-} openssl_algorithm_t;
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for encryption
- */
-static openssl_algorithm_t encryption_algs[] = {
-/*     {ENCR_DES_IV64,         "***",                  0,      0}, */
-       {ENCR_DES,                      "des",                  8,      8},             /* 64 bits */
-       {ENCR_3DES,             "des3",                 24,     24},    /* 192 bits */
-       {ENCR_RC5,                      "rc5",                  5,      255},   /* 40 to 2040 bits, RFC 2451 */
-       {ENCR_IDEA,             "idea",                 16,     16},    /* 128 bits, RFC 2451 */
-       {ENCR_CAST,             "cast",                 5,      16},    /* 40 to 128 bits, RFC 2451 */
-       {ENCR_BLOWFISH,         "blowfish",             5,      56},    /* 40 to 448 bits, RFC 2451 */
-/*     {ENCR_3IDEA,            "***",                  0,      0}, */
-/*     {ENCR_DES_IV32,         "***",                  0,      0}, */
-/*     {ENCR_NULL,             "***",                  0,      0}, */ /* handled separately */
-/*     {ENCR_AES_CBC,          "***",                  0,      0}, */ /* handled separately */
-/*     {ENCR_CAMELLIA_CBC,     "***",                  0,      0}, */ /* handled separately */
-/*     {ENCR_AES_CTR,          "***",                  0,      0}, */ /* disabled in evp.h */
-       {END_OF_LIST,           NULL,                   0,      0},
-};
-
-/**
  * Look up an OpenSSL algorithm name and validate its key size
  */
-static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
-                                          u_int16_t ikev2_algo, size_t *key_size)
+static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size)
 {
-       while (openssl_algo->ikev2_id != END_OF_LIST)
+       struct {
+               /* identifier specified in IKEv2 */
+               int ikev2_id;
+               /* name of the algorithm, as used in OpenSSL */
+               char *name;
+               /* default key size in bytes */
+               size_t key_def;
+               /* minimum key size */
+               size_t key_min;
+               /* maximum key size */
+               size_t key_max;
+       } mappings[] = {
+               {ENCR_DES,                      "des",                   8,              8,               8},
+               {ENCR_3DES,             "des3",                 24,             24,              24},
+               {ENCR_RC5,                      "rc5",                  16,              5,             255},
+               {ENCR_IDEA,             "idea",                 16,             16,              16},
+               {ENCR_CAST,             "cast",                 16,              5,              16},
+               {ENCR_BLOWFISH,         "blowfish",             16,              5,              56},
+       };
+       int i;
+
+       for (i = 0; i < countof(mappings); i++)
        {
-               if (ikev2_algo == openssl_algo->ikev2_id)
+               if (ikev2_algo == mappings[i].ikev2_id)
                {
                        /* set the key size if it is not set */
-                       if (*key_size == 0 &&
-                               (openssl_algo->key_size_min == openssl_algo->key_size_max))
+                       if (*key_size == 0)
                        {
-                               *key_size = openssl_algo->key_size_min;
+                               *key_size = mappings[i].key_def;
                        }
-
                        /* validate key size */
-                       if (*key_size < openssl_algo->key_size_min ||
-                               *key_size > openssl_algo->key_size_max)
+                       if (*key_size < mappings[i].key_min ||
+                               *key_size > mappings[i].key_max)
                        {
                                return NULL;
                        }
-                       return openssl_algo->name;
+                       return mappings[i].name;
                }
-               openssl_algo++;
        }
        return NULL;
 }
@@ -211,10 +180,14 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
        {
                case ENCR_NULL:
                        this->cipher = EVP_enc_null();
+                       key_size = 0;
                        break;
                case ENCR_AES_CBC:
                        switch (key_size)
                        {
+                               case 0:
+                                       key_size = 16;
+                                       /* FALL */
                                case 16:        /* AES 128 */
                                        this->cipher = EVP_get_cipherbyname("aes128");
                                        break;
@@ -232,6 +205,9 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
                case ENCR_CAMELLIA_CBC:
                        switch (key_size)
                        {
+                               case 0:
+                                       key_size = 16;
+                                       /* FALL */
                                case 16:        /* CAMELLIA 128 */
                                        this->cipher = EVP_get_cipherbyname("camellia128");
                                        break;
@@ -247,11 +223,14 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
                        }
                        break;
                case ENCR_DES_ECB:
+                       key_size = 8;
                        this->cipher = EVP_des_ecb();
                        break;
                default:
                {
-                       char* name = lookup_algorithm(encryption_algs, algo, &key_size);
+                       char* name;
+
+                       name = lookup_algorithm(algo, &key_size);
                        if (!name)
                        {
                                /* algo unavailable or key_size invalid */