Permalink
Browse files

HappyDance: Calculate Shannon Entropy of PSK and prepare to refuse we…

…ak PSKs

Currently, we warn at a Shannon Entropy value of < 3.5

The first libreswan release after July 1st, 2015 will refuse to use any
PSKs with entropy less than 3.5.
  • Loading branch information...
1 parent 1174992 commit e91abf0f527ccc2aca68d3afad7d0ec72bc8abe3 @letoams letoams committed Dec 30, 2014
Showing with 57 additions and 0 deletions.
  1. +2 −0 lib/libswan/internal.h
  2. +51 −0 lib/libswan/secrets.c
  3. +2 −0 programs/pluto/Makefile.options
  4. +2 −0 programs/showhostkey/Makefile
@@ -62,5 +62,7 @@
#define MALLOC(n) malloc(n)
#define FREE(p) free(p)
+#define MIN_SHANNON_ENTROPY 3.5
+
#endif /* __KERNEL__ */
View
@@ -19,6 +19,8 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
+#include <math.h>
+
#include <pthread.h> /* pthread.h must be first include file */
#include <stddef.h>
#include <stdlib.h>
@@ -57,6 +59,8 @@
#include <key.h>
#include "lswconf.h"
+#include "internal.h"
+
/* this does not belong here, but leave it here for now */
const struct id empty_id; /* ID_NONE */
@@ -87,6 +91,32 @@ static void lsw_process_secrets_file(struct secret **psecrets,
const char *file_pat);
+static double shannon_entropy(unsigned char *p, size_t size)
+{
+ double entropy = 0.0;
+ int histogram[256];
+ unsigned int i;
+
+ memset(histogram, 0, sizeof(int) * 256 );
+
+ for (i = 0; i < size; ++i)
+ ++histogram[p[i]];
+
+ for (i = 0; i < 256; ++i) {
+ if (histogram[i])
+ entropy -= (double)histogram[i] / size * log2((double)histogram[i]/size);
+ }
+ DBG(DBG_CONTROL,
+ DBG_log("Shannon entropy of PSK is %f", entropy));
+
+ if (entropy < MIN_SHANNON_ENTROPY) {
+ loglog(RC_LOG_SERIOUS,"WARNING: PSK entropy of %f is less than minimum Shannon Entropy of %f - this will be rejected as of July 1st, 2015",
+ entropy, MIN_SHANNON_ENTROPY);
+ }
+
+ return entropy;
+}
+
static void RSA_show_key_fields(struct RSA_private_key *k, int fieldcnt)
{
const struct fld *p;
@@ -732,10 +762,20 @@ static err_t lsw_process_rsa_keycert(struct RSA_private_key *rsak)
static err_t lsw_process_psk_secret(chunk_t *psk)
{
err_t ugh = NULL;
+ double shannon;
if (*flp->tok == '"' || *flp->tok == '\'') {
clonetochunk(*psk, flp->tok + 1, flp->cur - flp->tok - 2,
"PSK");
+ shannon = shannon_entropy(psk->ptr, psk->len);
+#ifdef AS_OF_JULY_1_2015
+ if (shannon < MIN_SHANNON_ENTROPY) {
+ ugh = builddiag("PSK entropy of %f is too weak - rejected (%s)", shannon, flp->tok);
+ libreswan_log("unloaded weak PSK");
+ freeanychunk(*psk);
+ } else
+#endif
+ DBG(DBG_CONTROLMORE, DBG_log("PSK entropy has Shannon Entropy of %f", shannon));
(void) shift();
} else {
char buf[RSA_MAX_ENCODING_BYTES]; /*
@@ -757,7 +797,16 @@ static err_t lsw_process_psk_secret(chunk_t *psk)
flp->tok);
} else {
clonetochunk(*psk, buf, sz, "PSK");
+ shannon = shannon_entropy(psk->ptr, psk->len);
+#ifdef AS_OF_JULY_1_2015
+ if (shannon < MIN_SHANNON_ENTROPY) {
+ ugh = builddiag("PSK entropy of %f is too weak - rejected (%s)", shannon, flp->tok);
+ libreswan_log("unloaded weak PSK");
+ freeanychunk(*psk);
+ } else
+#endif
(void) shift();
+ DBG(DBG_CONTROLMORE, DBG_log("PSK entropy has Shannon Entropy of %f", shannon));
}
}
@@ -1511,3 +1560,5 @@ void delete_public_keys(struct pubkey_list **head,
pp = &p->next;
}
}
+
+
@@ -122,6 +122,8 @@ BSDKAME_LIBS=${LIBBSDPFKEY}
endif
+PLUTOMINUSL+= -lm # for log2() for shannon_entropy()
+
# the files are defined here so that TAGS: can catch them.
#
X509_DIST_OBJS=x509.o x509more.o x509chain.o
@@ -19,5 +19,7 @@ PROGRAM=showhostkey
include ${srcdir}../Makefile.program
+CFLAGS+= -lm
+
# Enable for workaround for bug in nspr 4.8.2
#CFLAGS+=-Wno-strict-prototypes

0 comments on commit e91abf0

Please sign in to comment.