BeRTOS
pbkdf1.c
Go to the documentation of this file.
00001 
00038 #include "pbkdf1.h"
00039 #include <sec/hash.h>
00040 #include <sec/util.h>
00041 
00042 
00043 static void PBKDF1_begin(Kdf *ctx_, const char *pwd, size_t pwd_len,
00044                          const uint8_t *salt, size_t salt_len)
00045 {
00046     PBKDF1_Context *ctx = (PBKDF1_Context *)ctx_;
00047 
00048     hash_begin(ctx->hash);
00049     hash_update(ctx->hash, pwd, pwd_len);
00050     hash_update(ctx->hash, salt, salt_len);
00051     
00052     ctx->kdf.to_read = 0;
00053     ctx->kdf.block = NULL;
00054 }
00055 
00056 static void PBKDF1_next(Kdf *ctx_)
00057 {
00058     PBKDF1_Context *ctx = (PBKDF1_Context *)ctx_;
00059     
00060     // PBKDF1 will generate only one block of data (whose len depends
00061     // on the underlying hash function). After that, the generation stops
00062     // with an ASSERT. If you use PKBDF1, you are supposed to be aware
00063     // of this limit while designing your algorithm.
00064     ASSERT(ctx->kdf.block == NULL);
00065 
00066     int hlen = hash_digest_len(ctx->hash);
00067     uint8_t temp[hlen];
00068     uint8_t *final = hash_final(ctx->hash);
00069     
00070     for (uint32_t i=0; i<ctx->iterations-1; i++)
00071     {
00072         memcpy(temp, final, hlen);
00073         hash_begin(ctx->hash);
00074         hash_update(ctx->hash, temp, hlen);
00075         final = hash_final(ctx->hash);
00076     }
00077 
00078     PURGE(temp);
00079 
00080     ctx->kdf.to_read = ctx->kdf.block_len;
00081     ctx->kdf.block = final;
00082 }
00083 
00084 /**********************************************************************/
00085 
00086 // Default iteration count. The RFC does not specify a "good" default
00087 // value; it just says that this should be a high value to slow down
00088 // computations. Since slowing down is not much of a concern for an
00089 // embedded system, we settle for a value which is not too big.
00090 #define PBKDF1_DEFAULT_ITERATIONS      100
00091 
00092 
00093 void PBKDF1_init(PBKDF1_Context *ctx, Hash *h)
00094 {
00095     ctx->hash = h;
00096     ctx->iterations = PBKDF1_DEFAULT_ITERATIONS;
00097     ctx->kdf.begin = PBKDF1_begin;
00098     ctx->kdf.next = PBKDF1_next;
00099     ctx->kdf.block_len = hash_digest_len(h);
00100 }
00101 
00102 void PBKDF1_set_iterations(Kdf *ctx_, uint32_t iterations)
00103 {
00104     PBKDF1_Context *ctx = (PBKDF1_Context *)ctx_;
00105     ctx->iterations = iterations;
00106 }