/* scal-basic.c */ /* This file is part of the ARM-Crypto-Lib. Copyright (C) 2011 Daniel Otte (daniel.otte@rub.de) 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 #include "streamcipher_descriptor.h" #include "keysize_descriptor.h" #include "scal-basic.h" uint8_t scal_cipher_init(const scdesc_t* cipher_descriptor, const void* key, uint16_t keysize_b, const void* iv, uint16_t ivsize_b, scgen_ctx_t* ctx){ ctx->buffer = NULL; ctx->ctx = NULL; if(!is_valid_keysize_P(cipher_descriptor->valid_keysize_desc, keysize_b)){ return 1; } if(!is_valid_keysize_P(cipher_descriptor->valid_ivsize_desc, ivsize_b)){ return 2; } uint8_t flags; sc_init_fpt init_fpt; flags = cipher_descriptor->flags; ctx->desc_ptr = cipher_descriptor; ctx->keysize = keysize_b; ctx->ivsize = ivsize_b; ctx->ctx = malloc(cipher_descriptor->ctxsize_B); if(ctx->ctx==NULL){ return 3; } init_fpt = (cipher_descriptor->init); switch(flags&SC_INIT_TYPE){ case SC_INIT_TYPE_1: init_fpt.init1(key, ctx->ctx); break; case SC_INIT_TYPE_2: init_fpt.init2(key, iv, ctx->ctx); break; case SC_INIT_TYPE_3: init_fpt.init3(key, keysize_b, ctx->ctx); break; case SC_INIT_TYPE_4: init_fpt.init4(key, keysize_b, iv, ctx->ctx); break; case SC_INIT_TYPE_5: init_fpt.init5(key, keysize_b, iv, ivsize_b, ctx->ctx); break; default: return 4; } uint16_t blocksize_b; blocksize_b = cipher_descriptor->gensize_b; if(blocksize_b>8){ ctx->buffer=malloc((blocksize_b+7)/8); if(ctx->buffer==NULL){ return 5; } ctx->index=0; } return 0; } void scal_cipher_free(scgen_ctx_t* ctx){ if(ctx->buffer){ free(ctx->buffer); } if(ctx->ctx){ free(ctx->ctx); } } uint8_t scal_cipher_gen_byte(scgen_ctx_t* ctx){ uint8_t flags; uint16_t blocksize_b; void_fpt gen_fpt; flags = ctx->desc_ptr->flags; blocksize_b = ctx->desc_ptr->gensize_b; gen_fpt = (void_fpt)(ctx->desc_ptr->gen.genvoid); if(blocksize_b==8){ if((flags&SC_GEN_TYPE)==SC_GEN_TYPE_1){ return ((sc_gen1_fpt)gen_fpt)(ctx->ctx); }else{ uint8_t r; ((sc_gen2_fpt)gen_fpt)(&r, ctx->ctx); return r; } } if(blocksize_b<8){ uint8_t r=0; uint8_t fill=0; do{ r |= ((((sc_gen1_fpt)gen_fpt)(ctx->ctx))&(0xff<<(8-blocksize_b)))>>fill; fill += blocksize_b; }while(fill<8); return r; }else{ uint8_t r; if(ctx->index==0){ ((sc_gen2_fpt)gen_fpt)(ctx->buffer, ctx->ctx); ctx->index = blocksize_b; } r=ctx->buffer[(blocksize_b-ctx->index)/8]; ctx->index -= 8; return r; } } void scal_cipher_gen_block(void* block, scgen_ctx_t* ctx){ uint8_t flags; /* uint16_t blocksize_b; */ sc_gen_fpt gen_fpt; flags = ctx->desc_ptr->flags; /* blocksize_b = ctx->desc_ptr->gensize_b; */ gen_fpt = ctx->desc_ptr->gen; if((flags&SC_GEN_TYPE)==SC_GEN_TYPE_1){ *((uint8_t*)block) = gen_fpt.gen1(ctx->ctx); }else{ gen_fpt.gen2(block, ctx->ctx); } } void scal_cipher_gen_fillblock(void* block, uint16_t blocksize_B, scgen_ctx_t* ctx){ while(blocksize_B){ *((uint8_t*)block) = scal_cipher_gen_byte(ctx); block = (uint8_t*)block + 1; blocksize_B -= 1; } } uint16_t scal_cipher_getBlocksize_b(const scdesc_t* desc){ uint16_t blocksize_b; blocksize_b = desc->gensize_b; return blocksize_b; } void* scal_cipher_getKeysizeDesc(const scdesc_t* desc){ return (void*)(desc->valid_keysize_desc); } void* scal_cipher_getIVsizeDesc(const scdesc_t* desc){ return (void*)(desc->valid_ivsize_desc); }