Add support for SHA384 and SHA512, depref SHA256.

This changes the phase1 and phase2 proposals as follows:

1. Add SHA384 and SHA512 auth algorithms in ISAKMP proposals
   that have AES128 or AES256 encryption.
2. If the kernel supports SHA384 and SHA512, add them as phase 2
   auth algorithms, above SHA1 and SHA256.
3. List SHA1 before SHA256 (both after SHA512 and SHA384),
   because of the interoperability issues with SHA256.

The ISAKMP proposals don't have to check for kernel support
because they are implemented by racoon in userspace.

We move the code that configures the phase 2 proposals into its
own function because determining whether a given algorithm is
supported can only be done after pfkey_init is called.

Test: On kernel with no CONFIG_CRYPTO_SHA512, SHA1 is used.
Test: On kernel with CONFIG_CRYPTO_SHA512, SHA512 is used.
Bug: 34114242
Change-Id: I39e92cd41fde6a81266415b3696e024cf22270fb
diff --git a/setup.c b/setup.c
index fce9bf4..6f075f3 100644
--- a/setup.c
+++ b/setup.c
@@ -85,6 +85,26 @@
     }
 }
 
+static void add_sainfo() {
+    if (pk_checkalg(algclass_ipsec_auth, algtype_hmac_sha2_512, 0) == 0) {
+        add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_512, 0);
+    } else {
+        do_plog(LLV_WARNING, "Kernel does not support SHA512, not enabling\n");
+    }
+    if (pk_checkalg(algclass_ipsec_auth, algtype_hmac_sha2_384, 0) == 0) {
+        add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_384, 0);
+    } else {
+        do_plog(LLV_WARNING, "Kernel does not support SHA384, not enabling\n");
+    }
+    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0);
+    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, 0);
+    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0);
+    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256);
+    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
+    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
+    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
+}
+
 static void set_globals(char *server)
 {
     struct addrinfo hints = {
@@ -146,13 +166,6 @@
 
     sainfo.lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
     sainfo.lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
-    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA2_256, 0);
-    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_SHA1, 0);
-    add_sainfo_algorithm(algclass_ipsec_auth, IPSECDOI_ATTR_AUTH_HMAC_MD5, 0);
-    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 256);
-    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_AES, 128);
-    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_3DES, 0);
-    add_sainfo_algorithm(algclass_ipsec_enc, IPSECDOI_ESP_DES, 0);
 
     memset(script_names, 0, sizeof(script_names));
 }
@@ -419,8 +432,10 @@
         if (pfkey_init() < 0 || isakmp_init() < 0) {
             exit(1);
         }
+        add_sainfo();
         monitor_fd(localconf.sock_pfkey, (void *)pfkey_handler);
         add_isakmp_handler(myaddrs[0].sock, argv[1]);
+
 #ifdef ENABLE_NATT
         add_isakmp_handler(myaddrs[1].sock, argv[1]);
         natt_keepalive_init();
@@ -490,12 +505,20 @@
 
     /* Add proposals. */
     add_proposal(remoteconf, auth,
+            OAKLEY_ATTR_HASH_ALG_SHA2_512, OAKLEY_ATTR_ENC_ALG_AES, 256);
+    add_proposal(remoteconf, auth,
+            OAKLEY_ATTR_HASH_ALG_SHA2_384, OAKLEY_ATTR_ENC_ALG_AES, 256);
+    add_proposal(remoteconf, auth,
             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 256);
     add_proposal(remoteconf, auth,
             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 256);
     add_proposal(remoteconf, auth,
             OAKLEY_ATTR_HASH_ALG_MD5, OAKLEY_ATTR_ENC_ALG_AES, 256);
     add_proposal(remoteconf, auth,
+            OAKLEY_ATTR_HASH_ALG_SHA2_512, OAKLEY_ATTR_ENC_ALG_AES, 128);
+    add_proposal(remoteconf, auth,
+            OAKLEY_ATTR_HASH_ALG_SHA2_384, OAKLEY_ATTR_ENC_ALG_AES, 128);
+    add_proposal(remoteconf, auth,
             OAKLEY_ATTR_HASH_ALG_SHA2_256, OAKLEY_ATTR_ENC_ALG_AES, 128);
     add_proposal(remoteconf, auth,
             OAKLEY_ATTR_HASH_ALG_SHA, OAKLEY_ATTR_ENC_ALG_AES, 128);