Common stuff for all my devices' web server pages: css, login, log, ipv4, ipv6, firmware update, clock, reset info etc.

Dependents:   oldheating gps motorhome heating

Security

A password has to be set whenever there has been a software reset. Resets following faults or power on do not require a new password as the hash is restored from the RTC GPREG register.

The password is not saved on the device; instead a 32 bit hash of the password is saved. It would take 2^31 attempts to brute force the password: this could be done in under a month if an attempt were possible every millisecond. To prevent this a 200 ms delay is introduced in the reply to the login form, that gives a more reasonable 13 years to brute force the password.

Once the password is accepted a random session id is created. This is 36 bit to give six base 64 characters but without an extra delay. If an attempt could be made every ms then this would still take over a year to brute force.

The most likely attack would to use a dictionary with, say, 10 million entries against the password which would still take 20 days to do.

Committer:
andrewboyson
Date:
Mon Mar 18 11:23:09 2019 +0000
Revision:
71:d6aacc7d62ab
Child:
72:1ba60063c643
Tidied up the login module. In particular ensured that an empty sid could not be matched using a cookie with an empty value.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 71:d6aacc7d62ab 1 #include <stdbool.h>
andrewboyson 71:d6aacc7d62ab 2
andrewboyson 71:d6aacc7d62ab 3 #include "http.h"
andrewboyson 71:d6aacc7d62ab 4
andrewboyson 71:d6aacc7d62ab 5 #define GPREG2 (*((volatile unsigned *) 0x4002404C)) //This is the battery backed GPREG2 address
andrewboyson 71:d6aacc7d62ab 6 #define GPREG3 (*((volatile unsigned *) 0x40024050)) //This is the battery backed GPREG2 address
andrewboyson 71:d6aacc7d62ab 7
andrewboyson 71:d6aacc7d62ab 8 static char password[9]; //Initialised to an empty string but will never be NULL
andrewboyson 71:d6aacc7d62ab 9
andrewboyson 71:d6aacc7d62ab 10 static void passwordSave()
andrewboyson 71:d6aacc7d62ab 11 {
andrewboyson 71:d6aacc7d62ab 12 unsigned u;
andrewboyson 71:d6aacc7d62ab 13
andrewboyson 71:d6aacc7d62ab 14 u = password[ 0] << 0;
andrewboyson 71:d6aacc7d62ab 15 u |= password[ 1] << 8;
andrewboyson 71:d6aacc7d62ab 16 u |= password[ 2] << 16;
andrewboyson 71:d6aacc7d62ab 17 u |= password[ 3] << 24;
andrewboyson 71:d6aacc7d62ab 18 GPREG2 = u;
andrewboyson 71:d6aacc7d62ab 19 u = password[ 4] << 0;
andrewboyson 71:d6aacc7d62ab 20 u |= password[ 5] << 8;
andrewboyson 71:d6aacc7d62ab 21 u |= password[ 6] << 16;
andrewboyson 71:d6aacc7d62ab 22 u |= password[ 7] << 24;
andrewboyson 71:d6aacc7d62ab 23 GPREG3 = u;
andrewboyson 71:d6aacc7d62ab 24 }
andrewboyson 71:d6aacc7d62ab 25 void HttpLoginPasswordRestore()
andrewboyson 71:d6aacc7d62ab 26 {
andrewboyson 71:d6aacc7d62ab 27 unsigned u;
andrewboyson 71:d6aacc7d62ab 28
andrewboyson 71:d6aacc7d62ab 29 u = GPREG2;
andrewboyson 71:d6aacc7d62ab 30 password[ 0] = u >> 0;
andrewboyson 71:d6aacc7d62ab 31 password[ 1] = u >> 8;
andrewboyson 71:d6aacc7d62ab 32 password[ 2] = u >> 16;
andrewboyson 71:d6aacc7d62ab 33 password[ 3] = u >> 24;
andrewboyson 71:d6aacc7d62ab 34
andrewboyson 71:d6aacc7d62ab 35 u = GPREG3;
andrewboyson 71:d6aacc7d62ab 36 password[ 4] = u >> 0;
andrewboyson 71:d6aacc7d62ab 37 password[ 5] = u >> 8;
andrewboyson 71:d6aacc7d62ab 38 password[ 6] = u >> 16;
andrewboyson 71:d6aacc7d62ab 39 password[ 7] = u >> 24;
andrewboyson 71:d6aacc7d62ab 40 }
andrewboyson 71:d6aacc7d62ab 41
andrewboyson 71:d6aacc7d62ab 42 bool HttpLoginPasswordIsSet()
andrewboyson 71:d6aacc7d62ab 43 {
andrewboyson 71:d6aacc7d62ab 44 return password[0];
andrewboyson 71:d6aacc7d62ab 45 }
andrewboyson 71:d6aacc7d62ab 46 void HttpLoginPasswordSet(char* passwordFromQuery)
andrewboyson 71:d6aacc7d62ab 47 {
andrewboyson 71:d6aacc7d62ab 48 for (int i = 0; i < sizeof(password) - 1; i++) password[i] = passwordFromQuery[i];
andrewboyson 71:d6aacc7d62ab 49 passwordSave();
andrewboyson 71:d6aacc7d62ab 50 }
andrewboyson 71:d6aacc7d62ab 51 bool HttpLoginPasswordMatches(char* passwordFromQuery)
andrewboyson 71:d6aacc7d62ab 52 {
andrewboyson 71:d6aacc7d62ab 53 return HttpSameStr(passwordFromQuery, password);
andrewboyson 71:d6aacc7d62ab 54 }