monotone

monotone Mtn Source Tree

Root/botan/pkcs5.cpp

1/*************************************************
2* PKCS #5 Source File *
3* (C) 1999-2007 The Botan Project *
4*************************************************/
5
6#include <botan/pkcs5.h>
7#include <botan/lookup.h>
8#include <botan/loadstor.h>
9#include <botan/bit_ops.h>
10#include <botan/hmac.h>
11#include <algorithm>
12#include <memory>
13
14namespace Botan {
15
16/*************************************************
17* Return a PKCS#5 PBKDF1 derived key *
18*************************************************/
19OctetString PKCS5_PBKDF1::derive(u32bit key_len,
20 const std::string& passphrase,
21 const byte salt[], u32bit salt_size,
22 u32bit iterations) const
23 {
24 if(iterations == 0)
25 throw Invalid_Argument("PKCS#5 PBKDF1: Invalid iteration count");
26
27 std::auto_ptr<HashFunction> hash(get_hash(hash_name));
28 if(key_len > hash->OUTPUT_LENGTH)
29 throw Exception("PKCS#5 PBKDF1: Requested output length too long");
30
31 hash->update(passphrase);
32 hash->update(salt, salt_size);
33 SecureVector<byte> key = hash->final();
34
35 for(u32bit j = 1; j != iterations; ++j)
36 {
37 hash->update(key);
38 hash->final(key);
39 }
40
41 return OctetString(key, std::min(key_len, key.size()));
42 }
43
44/*************************************************
45* Return the name of this type *
46*************************************************/
47std::string PKCS5_PBKDF1::name() const
48 {
49 return "PBKDF1(" + hash_name + ")";
50 }
51
52/*************************************************
53* PKCS5_PBKDF1 Constructor *
54*************************************************/
55PKCS5_PBKDF1::PKCS5_PBKDF1(const std::string& h_name) : hash_name(h_name)
56 {
57 if(!have_hash(hash_name))
58 throw Algorithm_Not_Found(hash_name);
59 }
60
61/*************************************************
62* Return a PKCS#5 PBKDF2 derived key *
63*************************************************/
64OctetString PKCS5_PBKDF2::derive(u32bit key_len,
65 const std::string& passphrase,
66 const byte salt[], u32bit salt_size,
67 u32bit iterations) const
68 {
69 if(iterations == 0)
70 throw Invalid_Argument("PKCS#5 PBKDF2: Invalid iteration count");
71
72 if(passphrase.length() == 0)
73 throw Invalid_Argument("PKCS#5 PBKDF2: Empty passphrase is invalid");
74
75 HMAC hmac(hash_name);
76
77 hmac.set_key(reinterpret_cast<const byte*>(passphrase.data()),
78 passphrase.length());
79
80 SecureVector<byte> key(key_len);
81
82 byte* T = key.begin();
83
84 u32bit counter = 1;
85 while(key_len)
86 {
87 u32bit T_size = std::min(hmac.OUTPUT_LENGTH, key_len);
88 SecureVector<byte> U(hmac.OUTPUT_LENGTH);
89
90 hmac.update(salt, salt_size);
91 for(u32bit j = 0; j != 4; ++j)
92 hmac.update(get_byte(j, counter));
93 hmac.final(U);
94 xor_buf(T, U, T_size);
95
96 for(u32bit j = 1; j != iterations; ++j)
97 {
98 hmac.update(U);
99 hmac.final(U);
100 xor_buf(T, U, T_size);
101 }
102
103 key_len -= T_size;
104 T += T_size;
105 ++counter;
106 }
107
108 return key;
109 }
110
111/*************************************************
112* Return the name of this type *
113*************************************************/
114std::string PKCS5_PBKDF2::name() const
115 {
116 return "PBKDF2(" + hash_name + ")";
117 }
118
119/*************************************************
120* PKCS5_PBKDF2 Constructor *
121*************************************************/
122PKCS5_PBKDF2::PKCS5_PBKDF2(const std::string& h_name) : hash_name(h_name)
123 {
124 if(!have_hash(hash_name))
125 throw Algorithm_Not_Found(hash_name);
126 }
127
128}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status