/* libanode: the Anode C reference implementation * Copyright (C) 2009-2010 Adam Ierymenko * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "impl/aes.h" #include "impl/misc.h" #include "anode.h" #ifdef WINDOWS #include #include #endif struct AnodeSecureRandomImpl { AnodeAesExpandedKey key; unsigned char state[ANODE_AES_BLOCK_SIZE]; unsigned char block[ANODE_AES_BLOCK_SIZE]; unsigned int ptr; }; AnodeSecureRandom *AnodeSecureRandom_new() { unsigned char keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_BLOCK_SIZE + ANODE_AES_BLOCK_SIZE]; unsigned int i; struct AnodeSecureRandomImpl *srng; #ifdef WINDOWS HCRYPTPROV hProv; if (CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) { CryptGenRandom(hProv,sizeof(keybuf),keybuf); CryptReleaseContext(hProv,0); } #else FILE *urandf = fopen("/dev/urandom","rb"); if (urandf) { fread((void *)keybuf,sizeof(keybuf),1,urandf); fclose(urandf); } #endif for(i=0;i> 5); srng = malloc(sizeof(struct AnodeSecureRandomImpl)); Anode_aes256_expand_key(keybuf,&srng->key); for(i=0;istate[i] = keybuf[ANODE_AES_KEY_SIZE + i]; for(i=0;iblock[i] = keybuf[ANODE_AES_KEY_SIZE + ANODE_AES_KEY_SIZE + i]; srng->ptr = ANODE_AES_BLOCK_SIZE; return (AnodeSecureRandom *)srng; } void AnodeSecureRandom_gen_bytes(AnodeSecureRandom *srng,void *buf,long count) { long i,j; for(i=0;iptr == ANODE_AES_BLOCK_SIZE) { Anode_aes256_encrypt(&((struct AnodeSecureRandomImpl *)srng)->key,((struct AnodeSecureRandomImpl *)srng)->state,((struct AnodeSecureRandomImpl *)srng)->state); for(j=0;jblock[j] ^= ((struct AnodeSecureRandomImpl *)srng)->state[j]; ((struct AnodeSecureRandomImpl *)srng)->ptr = 0; } ((unsigned char *)buf)[i] = ((struct AnodeSecureRandomImpl *)srng)->block[((struct AnodeSecureRandomImpl *)srng)->ptr++]; } } void AnodeSecureRandom_delete(AnodeSecureRandom *srng) { free(srng); }