1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomCrypt, modular cryptographic library -- Tom St Denis 2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomCrypt is a library that provides various cryptographic 4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithms in a highly modular and flexible manner. 5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express 7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works. 8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com 10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "tomcrypt.h" 12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @file sober128.c 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Implementation of SOBER-128 by Tom St Denis. 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef SOBER128 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "sober128tab.c" 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectconst struct ltc_prng_descriptor sober128_desc = 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project "sober128", 64, 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_start, 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_add_entropy, 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_ready, 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_read, 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_done, 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_export, 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_import, 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &sober128_test 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}; 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* don't change these... */ 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define N 17 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define FOLD N /* how many iterations of folding to do */ 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define INITKONST 0x6996c53a /* value of KONST to use during key loading */ 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define KEYP 15 /* where to insert key words */ 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define FOLDP 4 /* where to insert non-linear feedback */ 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 BYTE2WORD(unsigned char *b) 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t; 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32L(t, b); 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return t; 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define WORD2BYTE(w, b) STORE32L(b, w) 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void XORWORD(ulong32 w, unsigned char *b) 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t; 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LOAD32L(t, b); 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t ^= w; 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STORE32L(t, b); 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* give correct offset for the current position of the register, 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * where logically R[0] is at position "zero". 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define OFF(zero, i) (((zero)+(i)) % N) 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* step the LFSR */ 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* After stepping, "zero" moves right one place */ 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define STEP(R,z) \ 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void cycle(ulong32 *R) 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t; 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project STEP(R,0); 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = R[0]; 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 1; i < N; ++i) { 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project R[i-1] = R[i]; 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project R[N-1] = t; 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Return a non-linear function of some parts of the register. 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define NLFUNC(c,z) \ 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ \ 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t ^= Sbox[(t >> 24) & 0xFF]; \ 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = RORc(t, 8); \ 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t ^= Sbox[(t >> 24) & 0xFF]; \ 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = t + c->R[OFF(z,13)]; \ 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic ulong32 nltap(struct sober128_prng *c) 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t; 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project NLFUNC(c, 0); 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return t; 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Start the PRNG 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng [out] The PRNG state to initialize 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_start(prng_state *prng) 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project struct sober128_prng *c; 113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c = &(prng->sober128); 117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Register initialised to Fibonacci numbers */ 119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[0] = 1; 120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[1] = 1; 121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 2; i < N; ++i) { 122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[i] = c->R[i-1] + c->R[i-2]; 123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->konst = INITKONST; 125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* next add_entropy will be the key */ 127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->flag = 1; 128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->set = 0; 129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Save the current register state 134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void s128_savestate(struct sober128_prng *c) 136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < N; ++i) { 139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->initR[i] = c->R[i]; 140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* initialise to previously saved register state 144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void s128_reloadstate(struct sober128_prng *c) 146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < N; ++i) { 150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[i] = c->initR[i]; 151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Initialise "konst" 155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void s128_genkonst(struct sober128_prng *c) 157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 newkonst; 159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project do { 161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cycle(c->R); 162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project newkonst = nltap(c); 163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } while ((newkonst & 0xFF000000) == 0); 164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->konst = newkonst; 165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Load key material into the register 168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define ADDKEY(k) \ 170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[KEYP] += (k); 171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define XORNL(nl) \ 173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->R[FOLDP] ^= (nl); 174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* nonlinear diffusion of register for key */ 176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; 177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void s128_diffuse(struct sober128_prng *c) 178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t; 180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* relies on FOLD == N == 17! */ 181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(0); 182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(1); 183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(2); 184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(3); 185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(4); 186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(5); 187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(6); 188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(7); 189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(8); 190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(9); 191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(10); 192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(11); 193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(12); 194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(13); 195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(14); 196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(15); 197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DROUND(16); 198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Add entropy to the PRNG state 202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param in The data to add 203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param inlen Length of the data to add 204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng PRNG state to update 205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) 208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project struct sober128_prng *c; 210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 i, k; 211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(in != NULL); 213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c = &(prng->sober128); 215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (c->flag == 1) { 217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* this is the first call to the add_entropy so this input is the key */ 218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* inlen must be multiple of 4 bytes */ 219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((inlen & 3) != 0) { 220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_KEYSIZE; 221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < inlen; i += 4) { 224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project k = BYTE2WORD((unsigned char *)&in[i]); 225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ADDKEY(k); 226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cycle(c->R); 227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XORNL(nltap(c)); 228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* also fold in the length of the key */ 231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ADDKEY(inlen); 232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* now diffuse */ 234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project s128_diffuse(c); 235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project s128_genkonst(c); 237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project s128_savestate(c); 238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->nbuf = 0; 239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->flag = 0; 240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->set = 1; 241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } else { 242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* ok we are adding an IV then... */ 243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project s128_reloadstate(c); 244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* inlen must be multiple of 4 bytes */ 246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((inlen & 3) != 0) { 247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_KEYSIZE; 248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < inlen; i += 4) { 251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project k = BYTE2WORD((unsigned char *)&in[i]); 252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ADDKEY(k); 253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cycle(c->R); 254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XORNL(nltap(c)); 255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* also fold in the length of the key */ 258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ADDKEY(inlen); 259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* now diffuse */ 261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project s128_diffuse(c); 262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->nbuf = 0; 263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Make the PRNG ready to read from 270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng The PRNG to make active 271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_ready(prng_state *prng) 274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR; 276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* XOR pseudo-random bytes into buffer 279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, out+(z*4)); 281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Read from the PRNG 284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param out Destination 285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param outlen Length of output 286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng The active PRNG to read from 287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return Number of octets read 288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectunsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng) 290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project struct sober128_prng *c; 292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ulong32 t, tlen; 293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(out != NULL); 295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef LTC_VALGRIND 298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project zeromem(out, outlen); 299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c = &(prng->sober128); 302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = 0; 303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project tlen = outlen; 304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* handle any previously buffered bytes */ 306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (c->nbuf != 0 && outlen != 0) { 307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *out++ ^= c->sbuf & 0xFF; 308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->sbuf >>= 8; 309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->nbuf -= 8; 310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project --outlen; 311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef LTC_SMALL_CODE 314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* do lots at a time, if there's enough to do */ 315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (outlen >= N*4) { 316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(0); 317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(1); 318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(2); 319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(3); 320f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(4); 321f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(5); 322f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(6); 323f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(7); 324f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(8); 325f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(9); 326f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(10); 327f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(11); 328f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(12); 329f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(13); 330f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(14); 331f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(15); 332f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project SROUND(16); 333f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project out += 4*N; 334f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project outlen -= 4*N; 335f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 336f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 337f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 338f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* do small or odd size buffers the slow way */ 339f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (4 <= outlen) { 340f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cycle(c->R); 341f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project t = nltap(c); 342f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XORWORD(t, out); 343f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project out += 4; 344f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project outlen -= 4; 345f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 346f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 347f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* handle any trailing bytes */ 348f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (outlen != 0) { 349f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cycle(c->R); 350f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->sbuf = nltap(c); 351f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->nbuf = 32; 352f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project while (c->nbuf != 0 && outlen != 0) { 353f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *out++ ^= c->sbuf & 0xFF; 354f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->sbuf >>= 8; 355f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project c->nbuf -= 8; 356f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project --outlen; 357f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 358f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 359f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 360f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return tlen; 361f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 362f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 363f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 364f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Terminate the PRNG 365f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng The PRNG to terminate 366f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 367f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 368f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_done(prng_state *prng) 369f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 370f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 371f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 372f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 373f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 374f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 375f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Export the PRNG state 376f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param out [out] Destination 377f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param outlen [in/out] Max size and resulting size of the state 378f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng The PRNG to export 379f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 380f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 381f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) 382f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 383f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(outlen != NULL); 384f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(out != NULL); 385f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 386f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 387f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (*outlen < 64) { 388f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *outlen = 64; 389f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_BUFFER_OVERFLOW; 390f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 391f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 392f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (sober128_read(out, 64, prng) != 64) { 393f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_ERROR_READPRNG; 394f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 395f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *outlen = 64; 396f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 397f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 398f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 399f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 400f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 401f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project Import a PRNG state 402f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param in The PRNG state 403f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param inlen Size of the state 404f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @param prng The PRNG to import 405f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful 406f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 407f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng) 408f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 409f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err; 410f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(in != NULL); 411f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project LTC_ARGCHK(prng != NULL); 412f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 413f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (inlen != 64) { 414f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_INVALID_ARG; 415f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 416f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 417f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_start(prng)) != CRYPT_OK) { 418f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 419f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 420f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) { 421f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 422f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 423f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return sober128_ready(prng); 424f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 425f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 426f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/** 427f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project PRNG self-test 428f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled 429f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project*/ 430f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint sober128_test(void) 431f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 432f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef LTC_TEST 433f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_NOP; 434f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else 435f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project static const struct { 436f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int keylen, ivlen, len; 437f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char key[16], iv[4], out[20]; 438f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } tests[] = { 439f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 440f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 441f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 16, 4, 20, 442f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 443f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* key */ 444f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, 445f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 }, 446f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 447f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* IV */ 448f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x00, 0x00, 0x00, 0x00 }, 449f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 450f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* expected output */ 451f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d, 452f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2, 453f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 0x40, 0x37, 0x8b, 0xbb } 454f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 455f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 456f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}; 457f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project prng_state prng; 458f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char dst[20]; 459f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int err, x; 460f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 461f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { 462f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_start(&prng)) != CRYPT_OK) { 463f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 464f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 465f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) { 466f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 467f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 468f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* add IV */ 469f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) { 470f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 471f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 472f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 473f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* ready up */ 474f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if ((err = sober128_ready(&prng)) != CRYPT_OK) { 475f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return err; 476f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 477f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project XMEMSET(dst, 0, tests[x].len); 478f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) { 479f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_ERROR_READPRNG; 480f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 481f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sober128_done(&prng); 482f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (XMEMCMP(dst, tests[x].out, tests[x].len)) { 483f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if 0 484f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project printf("\n\nSOBER128 failed, I got:\n"); 485f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]); 486f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project printf("\n"); 487f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 488f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_FAIL_TESTVECTOR; 489f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 490f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 491f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return CRYPT_OK; 492f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 493f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 494f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 495f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 496f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 497f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 498f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128.c,v $ */ 499f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.8 $ */ 500f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/11/05 00:11:36 $ */ 501