From df7e20c855a1be9efc9a224cf05c3ca7cf6128f0 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 10 Sep 2018 14:38:28 +0200 Subject: [PATCH] add protocol steps for the server --- PROTOCOL.md | 184 +++++++--------------------------------------------- 1 file changed, 25 insertions(+), 159 deletions(-) diff --git a/PROTOCOL.md b/PROTOCOL.md index 9e817bd..c94add3 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -128,7 +128,7 @@ Send $x_1$ and $x_2$. |:--------:|:------| | `1` | $t\_c = \mid \frac{t\_{now}}{W}\mid$ | | `2` | $x\_1 = h^{n}(K) \oplus h(t\_c)$ | -| `3` | Generate $(K',n',s')$ until
| +| `3` | Generate $(K',n',s')$ until
| | `4` | $x\_2 = h^{n'}(K') \oplus h(t\_c)$ | Send $x_1$ and $x_2$. @@ -145,174 +145,40 @@ This protocol is processed when the server sends the 2 hashes $(y_1, y_2)$ to th | `4` | $T = x\_1 \oplus h(t'\_s)$ | `5` | Find $N \in [min ; n-min[,\ h^{N}(K) = T$. | `6` | $x\_1 = h^N(K) \oplus h(t\_c)$ -| `7` | Generate $(K',n',s')$ until :
| +| `7` | Generate $(K',n',s')$ until :
| | `8` | $x\_2 = h^{n'}(K') \oplus h(t\_c)$ | Send $x_1$ and $x_2$. -## blablabla +## 2. Server management -##### Check a token +When receiving a pair of hashes $(x_1, x_2)$, the server has to : +1. Unscramble the request using the time-scrambling algorithm +2. Check the token held into $x_1$ : + - `VALID` $\rightarrow$ authenticated : store the token held into $x_2$, forward request to the logic unit + - `INVALID` $\rightarrow$ not authenticated : send the challenge hashes $(y_1, y_2)$. -When the client sends its next token $h^{n-1}(K)$, the server has to hash it and compare it with the last token $T$. In fact, tokens are generated according to the following property : -$$h(h^{n-1}) = h^n(K)$$ +#### 1. Unscramble the request -*In other words, each token is the hash of the next one.* +| Step | Calculation | +|:--------:|:------| +| `1` | $t\_s = \mid \frac{t\_{now}}{W}\mid, m\_s = t\_s \ \mathbb{Z}\_{(2)}$ | +| `2` | $m\_c = x\_1 \oplus x\_2$ | +| `3` | $t'\_c = t\_s - \parallel m_c - m_s \parallel$ | +| `4` | $t\_1 = x\_1 \oplus h(t'\_c)$ | +| `5` | $t\_2 = x\_2 \oplus h(t'\_c)$ | +| `6` | Token is valid if $h(t_1) = T$ | -Because of the main property of cryptographic hash functions, the original data is *cryprographically hard* to find from its *digest* (*i.e. the hashed data*). Since the next token is always the digest of the previous one (and not the opposite), an attacker has no clue about the next token. +#### 2. Invalid request management -**Limitations** : It seams obvious that there is weaknesses due to hashing recursively a single data, but I do not know if such attack is known or even works. - -##### Time Scrambling algorithm - -In order for the requests/responses to be only valid a few seconds in time, the tokens are scrambled using a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad). - -The sender processes the data as follows: - -| Step | Description | Formula | -|:----:|:-----------|:-------| -| 1 | Process the sender's time id | $t\_s = \mid \frac{t_{now}^s}{W} \mid $ | -| 2 | process the sender's time parity | $ m_s = t_s \mod 2$ | -| 3 | Send the time parity | $ Send\ m_s$ | - -The receiver has to guess $t_s$ with the following steps: - -| Step | Description | Formula | -|:----:|:-----------|:-------| -| 1 | receive the sender's time parity | $Receive \ m_s$ | -| 2 | process the receiver's time id | $t\_r = \mid \frac{t_{now}^r}{W} \mid $ | -| 3 | process the receiver's time parity | $m_r = t_r \mod 2$ | -| 4 | Try to guess the sender's time id | $t'_s2 = t_r - \parallel m_s - m_r \parallel $ | - -As a result, the receiver will only be able to retrieve the sender's time id if the reception time is at most $W$ seconds after the sending time : - -$$t\_{now}^r \in [t\_{now}^s ; t\_{now}^s + W] \Longrightarrow t\_s = t'_s2$$ - -In practice, the time id is **hashed** and used to achieve a [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) with the token. Because they both result from the same hash function their sizes are the same. - -As a result from the sent token $x_1 = token \oplus h(t_s)$, it is impossible to guess neither the token nor $h(t_s)$ without the other. - -**Explanation** -* The time id corresponds to the index of the time slice where slices are $W$ seconds wide. By dividing the time in slices of $W$ seconds, if we process the same calculation at an interval of $W$ or less seconds, we will have either the same result or a result greater by 1. -* The time id parity $m_s$ allows us to adjust the receiver's time id $t_r$ when it receives the request. This difference of 1 second is caused by the division of time in slices, the precision is also divided by $W$. - - - $t\_{now}\mod W = 0 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid $; no need for adjustment - - $t\_{now}\mod W = 1 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid + 1 $; need to subtract $1$ - - $t\_{now}\mod W = 2 \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now+(W-1)}}{W} \mid + 1 $; need to subtract $1$ - - $...$ - - $t\_{now}\mod W = (W-1) \Longrightarrow \mid \frac{t\_{now}}{W} \mid = \mid \frac{t\_{now}+(W-1)}{W} \mid + 1 $; need to subtract $1$ - -## Protocol properties - -##### (1) Token Chain - -As a result, each token is the digest* of its predecessor. ->_* : the output of the hash function._ - -This property allows the server to easily check if a token is valid by comparing it with the previous one $T$. It just has to check if the digest of the token is equal to the previous one. - -As a result, each token is bound to the previous one. If a request fails (*e.g. network issue*) and a token is lost, the next one won't be valid. +When receiving an invalid token, the server may sent back to the client a challenge to get the authentication back. This challenge is formed by 2 hashes $(y_1, y_2)$. -##### (2) Time Limitation - -Any request received more than $W$ seconds after being sent is invalidated by the server. It protects against manual, slow and process-intensive request forgery. Also a same token is *never* observed over the network. - -##### (3) Token unicity - -The clients never sends a token more than once. It avoids attackers to reuse tokens. Note that usually the client must not generate a same token twice. The keyset $(K, n, s)$ must never be used twice to generate tokens. - -##### (4) One-way Hash Chain - -For a given key, every token sent has a lower nonce $n$ than every other that has already been sent. In that way it gives no clue about the next tokens to be used. - - -##### Constraints - -- The server must be able to recover the token if the data is received within the time window. -- If the window expired, the token must be invalidated by the server. -- The server must be able to validate a token if it holds the previous one. -- The server must invalidate a token if it has not the previous one. -- The client must be able to recover the authentication with a challenge. - - -### Limitations - -- If an arbitrary catches, then blocks a request and sends it afterwards, it will be authenticated. This case is equivalent to being the client (with all secret variables), which can *never* occur if you use TLS. Notice that you won't be able to extract anything from the token anyway. -- With requests meta data (*e.g. HTTP headers containing the date*), an attacker knowing $W$ can forge the time hash $h(t_C)$ and be able to recover the private key $K$ by processing a simple *XOR* on the public token. Because the cyclic-hash algorithm generates a unique pseudo-random token from $K$ for each request, this case does not give the attacker any clue about the next token to be sent. - - - -## Protocol definition - -Each request will hold a pair of tokens $(x_1, x_2)$. If the server's check fails (*i.e. the client is not authenticated*), it will send back to the client a pair of tokens $(y_1, y_2)$ for resynchronization purposes. - -Each token has a size defined by the *hash function*, which is `sha512` for this specification ; the size is then 512 bits. - -> For readability purposes, the tokens are sent as their hexadecimal representation ; each token is then a string of 128 characters. - -### 1. Send the request - -This case is the default where $i$ is far from $1$ so there is no key generation or synchronization to do. - -| Step | Description | Formula | -|:----:|-------------|:--------| -| `c1` | Decrement the shifting nonce | $i = i - 1$ | -| `c2` | Calculate the one-time token | $T_c = h^{i}(K)$ | -| `c3` | Get the current time id | $t\_c =\ \mid \frac{t\_{now}}{W} \mid$ | -| `c4` | Calculate the parity of $t_c$ | $m_c = t_c \mod 2$ | -| `c5` | Calculate the time hash $h_{t_c}$ | $h_{t_c} = h(t_c)$ | -| `c6` | Calculate $x_1$, the scrambled *request token* | $x\_1 = T\_c \oplus h\_{t\_c}$ | -| `c7` | Calculate $x_2$, the scrambled *next token* | $x_2 = x_1 \oplus m_c$ | - -**Security** : We process a one-time pad between $T_c$ and $h_{t_c}$ it is crucial that both values have the same size of $L$ bits. It makes $T_c$ impossible to extract without having the value $h_{t_c}$, this property applies in both ways. - - -**Short formulas** - -| Field | Short formula | -| :-----------: | ------------------------------------------------ | -| $t_c$ | $\mid\frac{t_{now}}{W}\mid$ | -| $x_1$ | $h^{i}(K) \oplus h(t_c)$ | -| $x_2$ | $x_1 \oplus (t_c \mod 2)$ | - -Send $(x_1, x_2)$. - - -### 2. Receive the request - -The server receives $(x_1, x_2)$. It does have to : -1. Guess the client's time id to un-scramble the token -2. Check the token - -| Step | Description | Formula | -|:----:|-------------|:--------| -| `s1` | Extract the client's time parity | $m_c = x_1 \oplus x_2$ | -| `s2` | Get the current time id | $t\_s =\ \mid \frac{t_{now}}{W} \mid$ | -| `s3` | Calculate the parity of $t_s$ | $m_s = t_s \mod 2$ | -| `s4` | Guess the client's time id | $t'_c = t_s - \parallel m_s - m_c \parallel$ | -| `s5` | Calculate the time hash $h_{t'_c}$ | $h_{t'_c} = h(t'_c)$ | -| `s6` | Extract the token $T'_c$ | $T'\_c = x_1 \oplus h\_{t'\_c}$ | -| `s7` | Extract the next token $T_{next}$ | $T\_{next} = x\_2 \oplus m\_c \oplus h\_{t'\_c}$ | -| `s8` | Check the token | $h(T'\_c) = T \Longrightarrow T = T_{next}$ | - -If the token is valid on step `s8`, the next validation token $T_{next}$ is stored and the request can be processed by the server. If the token mismatches, the recovery mode is enabled. - -**Short formulas** - -​ The whole unscrambling process can be shortened into the following formula resulting in $0$ if the client is authenticated. - -$$x\_1 \oplus h(\mid \frac{t\_{now}}{W}\mid - \parallel (x\_1 \oplus x\_2) - (\mid \frac{t\_{now}}{W}\mid \mod 2) \parallel) \oplus T$$ - -| Step | Description | Formula | -|:----:|-------------|:--------| -| `rs1` | Get the current time id | $t\_s = \mid \frac{t\_{now}}{W} \mid$ | -| `rs2` | Calculate the parity of $t_s$ | $m_s = t_s \mod 2$ | -| `rs3` | Calculate the time hash $h_{t_s}$ | $h_{t_s} = h(t_s)$ | -| `rs4` | Calculate $y_1$, the recovery hash | $y\_1 = T \oplus h\_{t_s}$ | -| `rs5` | Calculate $y_2$, used for parity | $y_2 = y_1 \oplus m_s$ | - -Send $(y_1, y_2)$. - +| Step | Calculation | +|:--------:|:------| +| `1` | $t\_s = \mid \frac{t\_{now}}{W}\mid$ | +| `2` | $y\_1 = T \oplus h(t\_c)$ | +| `3` | $y\_2 = y\_1 \oplus (t\_c \ \mathbb{Z}\_{(2)})$ | +Send $y_1$ and $y_2$. \ No newline at end of file