Skip to content

Commit e91abf0

Browse files
committed
HappyDance: Calculate Shannon Entropy of PSK and prepare to refuse weak 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.
1 parent 1174992 commit e91abf0

File tree

4 files changed

+57
-0
lines changed

4 files changed

+57
-0
lines changed

lib/libswan/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,7 @@
6262
#define MALLOC(n) malloc(n)
6363
#define FREE(p) free(p)
6464

65+
#define MIN_SHANNON_ENTROPY 3.5
66+
6567
#endif /* __KERNEL__ */
6668

lib/libswan/secrets.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2020
* for more details.
2121
*/
22+
#include <math.h>
23+
2224
#include <pthread.h> /* pthread.h must be first include file */
2325
#include <stddef.h>
2426
#include <stdlib.h>
@@ -57,6 +59,8 @@
5759
#include <key.h>
5860
#include "lswconf.h"
5961

62+
#include "internal.h"
63+
6064
/* this does not belong here, but leave it here for now */
6165
const struct id empty_id; /* ID_NONE */
6266

@@ -87,6 +91,32 @@ static void lsw_process_secrets_file(struct secret **psecrets,
8791
const char *file_pat);
8892

8993

94+
static double shannon_entropy(unsigned char *p, size_t size)
95+
{
96+
double entropy = 0.0;
97+
int histogram[256];
98+
unsigned int i;
99+
100+
memset(histogram, 0, sizeof(int) * 256 );
101+
102+
for (i = 0; i < size; ++i)
103+
++histogram[p[i]];
104+
105+
for (i = 0; i < 256; ++i) {
106+
if (histogram[i])
107+
entropy -= (double)histogram[i] / size * log2((double)histogram[i]/size);
108+
}
109+
DBG(DBG_CONTROL,
110+
DBG_log("Shannon entropy of PSK is %f", entropy));
111+
112+
if (entropy < MIN_SHANNON_ENTROPY) {
113+
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",
114+
entropy, MIN_SHANNON_ENTROPY);
115+
}
116+
117+
return entropy;
118+
}
119+
90120
static void RSA_show_key_fields(struct RSA_private_key *k, int fieldcnt)
91121
{
92122
const struct fld *p;
@@ -732,10 +762,20 @@ static err_t lsw_process_rsa_keycert(struct RSA_private_key *rsak)
732762
static err_t lsw_process_psk_secret(chunk_t *psk)
733763
{
734764
err_t ugh = NULL;
765+
double shannon;
735766

736767
if (*flp->tok == '"' || *flp->tok == '\'') {
737768
clonetochunk(*psk, flp->tok + 1, flp->cur - flp->tok - 2,
738769
"PSK");
770+
shannon = shannon_entropy(psk->ptr, psk->len);
771+
#ifdef AS_OF_JULY_1_2015
772+
if (shannon < MIN_SHANNON_ENTROPY) {
773+
ugh = builddiag("PSK entropy of %f is too weak - rejected (%s)", shannon, flp->tok);
774+
libreswan_log("unloaded weak PSK");
775+
freeanychunk(*psk);
776+
} else
777+
#endif
778+
DBG(DBG_CONTROLMORE, DBG_log("PSK entropy has Shannon Entropy of %f", shannon));
739779
(void) shift();
740780
} else {
741781
char buf[RSA_MAX_ENCODING_BYTES]; /*
@@ -757,7 +797,16 @@ static err_t lsw_process_psk_secret(chunk_t *psk)
757797
flp->tok);
758798
} else {
759799
clonetochunk(*psk, buf, sz, "PSK");
800+
shannon = shannon_entropy(psk->ptr, psk->len);
801+
#ifdef AS_OF_JULY_1_2015
802+
if (shannon < MIN_SHANNON_ENTROPY) {
803+
ugh = builddiag("PSK entropy of %f is too weak - rejected (%s)", shannon, flp->tok);
804+
libreswan_log("unloaded weak PSK");
805+
freeanychunk(*psk);
806+
} else
807+
#endif
760808
(void) shift();
809+
DBG(DBG_CONTROLMORE, DBG_log("PSK entropy has Shannon Entropy of %f", shannon));
761810
}
762811
}
763812

@@ -1511,3 +1560,5 @@ void delete_public_keys(struct pubkey_list **head,
15111560
pp = &p->next;
15121561
}
15131562
}
1563+
1564+

programs/pluto/Makefile.options

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ BSDKAME_LIBS=${LIBBSDPFKEY}
122122
endif
123123

124124

125+
PLUTOMINUSL+= -lm # for log2() for shannon_entropy()
126+
125127
# the files are defined here so that TAGS: can catch them.
126128
#
127129
X509_DIST_OBJS=x509.o x509more.o x509chain.o

programs/showhostkey/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ PROGRAM=showhostkey
1919

2020
include ${srcdir}../Makefile.program
2121

22+
CFLAGS+= -lm
23+
2224
# Enable for workaround for bug in nspr 4.8.2
2325
#CFLAGS+=-Wno-strict-prototypes

0 commit comments

Comments
 (0)