BeRTOS
|
00001 00038 #include "pbkdf2.h" 00039 #include <cpu/byteorder.h> 00040 #include <sec/util.h> 00041 #include <cfg/debug.h> 00042 00043 static void PBKDF2_begin(Kdf *ctx_, const char *pwd, size_t pwd_len, 00044 const uint8_t *salt, size_t salt_len) 00045 { 00046 PBKDF2_Context *ctx = (PBKDF2_Context*)ctx_; 00047 00048 ASSERT(sizeof(ctx->salt) >= salt_len); 00049 00050 mac_set_key(ctx->mac, (const uint8_t*)pwd, pwd_len); 00051 ctx->salt_len = salt_len; 00052 memcpy(ctx->salt, salt, salt_len); 00053 ctx->c = 0; 00054 ctx->kdf.to_read = 0; 00055 ctx->kdf.block = NULL; 00056 } 00057 00058 static void PBKDF2_next(Kdf *ctx_) 00059 { 00060 PBKDF2_Context *ctx = (PBKDF2_Context*)ctx_; 00061 int dlen = mac_digest_len(ctx->mac); 00062 uint8_t last[dlen]; 00063 00064 ++ctx->c; 00065 uint32_t bec = cpu_to_be32(ctx->c); 00066 00067 mac_begin(ctx->mac); 00068 mac_update(ctx->mac, ctx->salt, ctx->salt_len); 00069 mac_update(ctx->mac, &bec, 4); 00070 memcpy(last, mac_final(ctx->mac), dlen); 00071 memcpy(ctx->block, last, dlen); 00072 00073 for (uint32_t i=0; i<ctx->iterations-1; ++i) 00074 { 00075 mac_begin(ctx->mac); 00076 mac_update(ctx->mac, last, dlen); 00077 memcpy(last, mac_final(ctx->mac), dlen); 00078 xor_block(ctx->block, ctx->block, last, dlen); 00079 } 00080 00081 ctx->kdf.to_read = dlen; 00082 ctx->kdf.block = ctx->block; 00083 00084 PURGE(last); 00085 } 00086 00087 00088 /**********************************************************************/ 00089 00090 // Default iteration count. The RFC does not specify a "good" default 00091 // value; it just says that this should be a high value to slow down 00092 // computations. Since slowing down is not much of a concern for an 00093 // embedded system, we settle for a value which is not too big. 00094 #define PBKDF2_DEFAULT_ITERATIONS 100 00095 00096 00097 void PBKDF2_init(PBKDF2_Context *ctx, Mac *mac) 00098 { 00099 ctx->salt_len = 0; 00100 ctx->mac = mac; 00101 ctx->iterations = PBKDF2_DEFAULT_ITERATIONS; 00102 ctx->kdf.begin = PBKDF2_begin; 00103 ctx->kdf.next = PBKDF2_next; 00104 ctx->kdf.block_len = mac_digest_len(mac); 00105 ASSERT(ctx->kdf.block_len <= sizeof(ctx->block)); 00106 } 00107 00108 void PBKDF2_set_iterations(Kdf *ctx_, uint32_t iterations) 00109 { 00110 PBKDF2_Context *ctx = (PBKDF2_Context*)ctx_; 00111 ctx->iterations = iterations; 00112 } 00113