Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
35c675a7
Commit
35c675a7
authored
Jul 18, 2005
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fortuna fixes. Marko Kreen
parent
2787db9b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
193 additions
and
88 deletions
+193
-88
contrib/pgcrypto/fortuna.c
contrib/pgcrypto/fortuna.c
+108
-53
contrib/pgcrypto/fortuna.h
contrib/pgcrypto/fortuna.h
+2
-8
contrib/pgcrypto/internal.c
contrib/pgcrypto/internal.c
+39
-6
contrib/pgcrypto/pgp-pgsql.c
contrib/pgcrypto/pgp-pgsql.c
+40
-17
contrib/pgcrypto/pgp-s2k.c
contrib/pgcrypto/pgp-s2k.c
+4
-4
No files found.
contrib/pgcrypto/fortuna.c
View file @
35c675a7
...
...
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.
3 2005/07/18 17:09:01
tgl Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.c,v 1.
4 2005/07/18 17:12:54
tgl Exp $
*/
#include "postgres.h"
...
...
@@ -94,14 +94,16 @@
/* for one big request, reseed after this many bytes */
#define RESEED_BYTES (1024*1024)
/*
* Skip reseed if pool 0 has less than this many
* bytes added since last reseed.
*/
#define POOL0_FILL (256/8)
/*
* Algorithm constants
*/
/* max sources */
#define MAX_SOURCES 8
/* Both cipher key size and hash result size */
#define BLOCK 32
...
...
@@ -118,9 +120,11 @@ struct fortuna_state {
uint8
key
[
BLOCK
];
MD_CTX
pool
[
NUM_POOLS
];
CIPH_CTX
ciph
;
unsigned
source_pos
[
MAX_SOURCES
];
unsigned
reseed_count
;
struct
timeval
last_reseed_time
;
unsigned
pool0_bytes
;
unsigned
rnd_pos
;
int
counter_init
;
};
typedef
struct
fortuna_state
FState
;
...
...
@@ -161,7 +165,6 @@ static void md_result(MD_CTX *ctx, uint8 *dst)
memset
(
&
tmp
,
0
,
sizeof
(
tmp
));
}
/*
* initialize state
*/
...
...
@@ -173,6 +176,32 @@ static void init_state(FState *st)
md_init
(
&
st
->
pool
[
i
]);
}
/*
* Endianess does not matter.
* It just needs to change without repeating.
*/
static
void
inc_counter
(
FState
*
st
)
{
uint32
*
val
=
(
uint32
*
)
st
->
counter
;
if
(
++
val
[
0
])
return
;
if
(
++
val
[
1
])
return
;
if
(
++
val
[
2
])
return
;
++
val
[
3
];
}
/*
* This is called 'cipher in counter mode'.
*/
static
void
encrypt_counter
(
FState
*
st
,
uint8
*
dst
)
{
ciph_encrypt
(
&
st
->
ciph
,
st
->
counter
,
dst
);
inc_counter
(
st
);
}
/*
* The time between reseed must be at least RESEED_INTERVAL
* microseconds.
...
...
@@ -207,9 +236,8 @@ static void reseed(FState *st)
MD_CTX
key_md
;
uint8
buf
[
BLOCK
];
/* check frequency */
if
(
too_often
(
st
))
return
;
/* set pool as empty */
st
->
pool0_bytes
=
0
;
/*
* Both #0 and #1 reseed would use only pool 0.
...
...
@@ -243,50 +271,81 @@ static void reseed(FState *st)
memset
(
buf
,
0
,
BLOCK
);
}
/*
* Pick a random pool. This uses key bytes as random source.
*/
static
unsigned
get_rand_pool
(
FState
*
st
)
{
unsigned
rnd
;
/*
* This slightly prefers lower pools - thats OK.
*/
rnd
=
st
->
key
[
st
->
rnd_pos
]
%
NUM_POOLS
;
st
->
rnd_pos
++
;
if
(
st
->
rnd_pos
>=
BLOCK
)
st
->
rnd_pos
=
0
;
return
rnd
;
}
/*
* update pools
*/
static
void
add_entropy
(
FState
*
st
,
unsigned
src_id
,
const
uint8
*
data
,
unsigned
len
)
static
void
add_entropy
(
FState
*
st
,
const
uint8
*
data
,
unsigned
len
)
{
unsigned
pos
;
uint8
hash
[
BLOCK
];
MD_CTX
md
;
/* just in case there's a bug somewhere */
if
(
src_id
>=
MAX_SOURCES
)
src_id
=
USER_ENTROPY
;
/* hash given data */
md_init
(
&
md
);
md_update
(
&
md
,
data
,
len
);
md_result
(
&
md
,
hash
);
/* update pools round-robin manner */
pos
=
st
->
source_pos
[
src_id
];
/*
* Make sure the pool 0 is initialized,
* then update randomly.
*/
if
(
st
->
reseed_count
==
0
&&
st
->
pool0_bytes
<
POOL0_FILL
)
pos
=
0
;
else
pos
=
get_rand_pool
(
st
);
md_update
(
&
st
->
pool
[
pos
],
hash
,
BLOCK
);
if
(
++
pos
>=
NUM_POOLS
)
pos
=
0
;
st
->
source_pos
[
src_id
]
=
pos
;
if
(
pos
==
0
)
st
->
pool0_bytes
+=
len
;
memset
(
hash
,
0
,
BLOCK
);
memset
(
&
md
,
0
,
sizeof
(
md
));
}
/*
* Endianess does not matter.
* It just needs to change without repeating.
* Just take 2 next blocks as new key
*/
static
void
inc_counter
(
FState
*
st
)
static
void
rekey
(
FState
*
st
)
{
uint32
*
val
=
(
uint32
*
)
st
->
counter
;
if
(
++
val
[
0
])
return
;
if
(
++
val
[
1
])
return
;
if
(
++
val
[
2
])
return
;
++
val
[
3
];
encrypt_counter
(
st
,
st
->
key
);
encrypt_counter
(
st
,
st
->
key
+
CIPH_BLOCK
);
ciph_init
(
&
st
->
ciph
,
st
->
key
,
BLOCK
);
}
/*
* Fortuna relies on AES standing known-plaintext attack.
* In case it does not, slow down the attacker by initialising
* the couter to random value.
*/
static
void
init_counter
(
FState
*
st
)
{
/* Use next block as counter. */
encrypt_counter
(
st
,
st
->
counter
);
/* Hide the key. */
rekey
(
st
);
/* The counter can be shuffled only once. */
st
->
counter_init
=
1
;
}
static
void
extract_data
(
FState
*
st
,
unsigned
count
,
uint8
*
dst
)
...
...
@@ -294,31 +353,17 @@ static void extract_data(FState *st, unsigned count, uint8 *dst)
unsigned
n
;
unsigned
block_nr
=
0
;
/*
* Every request should be with different key,
* if possible.
*/
reseed
(
st
);
/* Can we reseed? */
if
(
st
->
pool0_bytes
>=
POOL0_FILL
&&
!
too_often
(
st
))
reseed
(
st
);
/*
* If the reseed didn't happen, don't use the old data
* rather encrypt again.
*/
/* Is counter initialized? */
if
(
!
st
->
counter_init
)
init_counter
(
st
);
while
(
count
>
0
)
{
/* must not give out too many bytes with one key */
if
(
block_nr
>
(
RESEED_BYTES
/
CIPH_BLOCK
))
{
reseed
(
st
);
block_nr
=
0
;
}
/* produce bytes */
ciph_encrypt
(
&
st
->
ciph
,
st
->
counter
,
st
->
result
);
block_nr
++
;
/* prepare for next time */
inc_counter
(
st
);
encrypt_counter
(
st
,
st
->
result
);
/* copy result */
if
(
count
>
CIPH_BLOCK
)
...
...
@@ -328,7 +373,17 @@ static void extract_data(FState *st, unsigned count, uint8 *dst)
memcpy
(
dst
,
st
->
result
,
n
);
dst
+=
n
;
count
-=
n
;
/* must not give out too many bytes with one key */
block_nr
++
;
if
(
block_nr
>
(
RESEED_BYTES
/
CIPH_BLOCK
))
{
rekey
(
st
);
block_nr
=
0
;
}
}
/* Set new key for next request. */
rekey
(
st
);
}
/*
...
...
@@ -338,7 +393,7 @@ static void extract_data(FState *st, unsigned count, uint8 *dst)
static
FState
main_state
;
static
int
init_done
=
0
;
void
fortuna_add_entropy
(
unsigned
src_id
,
const
uint8
*
data
,
unsigned
len
)
void
fortuna_add_entropy
(
const
uint8
*
data
,
unsigned
len
)
{
if
(
!
init_done
)
{
...
...
@@ -347,7 +402,7 @@ void fortuna_add_entropy(unsigned src_id, const uint8 *data, unsigned len)
}
if
(
!
data
||
!
len
)
return
;
add_entropy
(
&
main_state
,
src_id
,
data
,
len
);
add_entropy
(
&
main_state
,
data
,
len
);
}
void
fortuna_get_bytes
(
unsigned
len
,
uint8
*
dst
)
...
...
contrib/pgcrypto/fortuna.h
View file @
35c675a7
...
...
@@ -26,20 +26,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.h,v 1.
1 2005/07/10 13:46:28 momjian
Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/fortuna.h,v 1.
2 2005/07/18 17:12:54 tgl
Exp $
*/
#ifndef __FORTUNA_H
#define __FORTUNA_H
/*
* Event source ID's
*/
#define SYSTEM_ENTROPY 0
#define USER_ENTROPY 1
void
fortuna_get_bytes
(
unsigned
len
,
uint8
*
dst
);
void
fortuna_add_entropy
(
unsigned
src_id
,
const
uint8
*
data
,
unsigned
len
);
void
fortuna_add_entropy
(
const
uint8
*
data
,
unsigned
len
);
#endif
contrib/pgcrypto/internal.c
View file @
35c675a7
...
...
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.2
1 2005/07/18 17:09:01
tgl Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/internal.c,v 1.2
2 2005/07/18 17:12:54
tgl Exp $
*/
#include "postgres.h"
...
...
@@ -42,9 +42,22 @@
#include "fortuna.h"
/*
*
How often to try to acquire system entropy. (In seconds)
*
System reseeds should be separated at least this much.
*/
#define SYSTEM_RESEED_FREQ (3*60*60)
#define SYSTEM_RESEED_MIN (20*60)
/* 20 min */
/*
* How often to roll dice.
*/
#define SYSTEM_RESEED_CHECK_TIME (10*60)
/* 10 min */
/*
* The chance is x/256 that the reseed happens.
*/
#define SYSTEM_RESEED_CHANCE (4)
/* 256/4 * 10min ~ 10h */
/*
* If this much time has passed, force reseed.
*/
#define SYSTEM_RESEED_MAX (12*60*60)
/* 12h */
#ifndef MD5_DIGEST_LENGTH
...
...
@@ -823,20 +836,40 @@ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
}
static
time_t
seed_time
=
0
;
static
time_t
check_time
=
0
;
static
void
system_reseed
(
void
)
{
uint8
buf
[
1024
];
int
n
;
time_t
t
;
int
skip
=
1
;
t
=
time
(
NULL
);
if
(
seed_time
&&
(
t
-
seed_time
)
<
SYSTEM_RESEED_FREQ
)
if
(
seed_time
==
0
)
skip
=
0
;
else
if
((
t
-
seed_time
)
<
SYSTEM_RESEED_MIN
)
skip
=
1
;
else
if
((
t
-
seed_time
)
>
SYSTEM_RESEED_MAX
)
skip
=
0
;
else
if
(
!
check_time
||
(
t
-
check_time
)
>
SYSTEM_RESEED_CHECK_TIME
)
{
check_time
=
t
;
/* roll dice */
px_get_random_bytes
(
buf
,
1
);
skip
=
buf
[
0
]
>=
SYSTEM_RESEED_CHANCE
;
}
/* clear 1 byte */
memset
(
buf
,
0
,
sizeof
(
buf
));
if
(
skip
)
return
;
n
=
px_acquire_system_randomness
(
buf
);
if
(
n
>
0
)
fortuna_add_entropy
(
SYSTEM_ENTROPY
,
buf
,
n
);
fortuna_add_entropy
(
buf
,
n
);
seed_time
=
t
;
memset
(
buf
,
0
,
sizeof
(
buf
));
...
...
@@ -854,7 +887,7 @@ int
px_add_entropy
(
const
uint8
*
data
,
unsigned
count
)
{
system_reseed
();
fortuna_add_entropy
(
USER_ENTROPY
,
data
,
count
);
fortuna_add_entropy
(
data
,
count
);
return
0
;
}
contrib/pgcrypto/pgp-pgsql.c
View file @
35c675a7
...
...
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.
2 2005/07/11 15:07:59
tgl Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-pgsql.c,v 1.
3 2005/07/18 17:12:54
tgl Exp $
*/
#include "postgres.h"
...
...
@@ -86,6 +86,22 @@ PG_FUNCTION_INFO_V1(pg_dearmor);
} \
} while (0)
/*
* Mix a block of data into RNG.
*/
static
void
add_block_entropy
(
PX_MD
*
md
,
text
*
data
)
{
uint8
sha1
[
20
];
px_md_reset
(
md
);
px_md_update
(
md
,
VARDATA
(
data
),
VARSIZE
(
data
)
-
VARHDRSZ
);
px_md_finish
(
md
,
sha1
);
px_add_entropy
(
sha1
,
20
);
memset
(
sha1
,
0
,
20
);
}
/*
* Mix user data into RNG. It is for user own interests to have
* RNG state shuffled.
...
...
@@ -93,31 +109,38 @@ PG_FUNCTION_INFO_V1(pg_dearmor);
static
void
add_entropy
(
text
*
data1
,
text
*
data2
,
text
*
data3
)
{
PX_MD
*
md
;
uint8
sha1
[
20
];
int
res
;
uint8
rnd
[
3
];
if
(
!
data1
&&
!
data2
&&
!
data3
)
return
;
res
=
px_find_digest
(
"sha1"
,
&
md
);
if
(
res
<
0
)
if
(
px_get_random_bytes
(
rnd
,
3
)
<
0
)
return
;
if
(
data1
)
px_md_update
(
md
,
VARDATA
(
data1
),
VARSIZE
(
data1
)
-
VARHDRSZ
);
if
(
data2
)
px_md_update
(
md
,
VARDATA
(
data2
),
VARSIZE
(
data2
)
-
VARHDRSZ
);
if
(
data3
)
px_md_update
(
md
,
VARDATA
(
data3
),
VARSIZE
(
data3
)
-
VARHDRSZ
);
if
(
px_find_digest
(
"sha1"
,
&
md
)
<
0
)
return
;
px_md_finish
(
md
,
sha1
);
px_md_free
(
md
);
/*
* Try to make the feeding unpredictable.
*
* Prefer data over keys, as it's rather likely
* that key is same in several calls.
*/
res
=
px_add_entropy
(
sha1
,
20
);
memset
(
sha1
,
0
,
20
);
/* chance: 7/8 */
if
(
data1
&&
rnd
[
0
]
>=
32
)
add_block_entropy
(
md
,
data1
);
/* chance: 5/8 */
if
(
data2
&&
rnd
[
1
]
>=
160
)
add_block_entropy
(
md
,
data2
);
if
(
res
<
0
)
ereport
(
NOTICE
,
(
errmsg
(
"add_entropy: %s"
,
px_strerror
(
res
))));
/* chance: 5/8 */
if
(
data3
&&
rnd
[
2
]
>=
160
)
add_block_entropy
(
md
,
data3
);
px_md_free
(
md
);
memset
(
rnd
,
0
,
sizeof
(
rnd
));
}
/*
...
...
contrib/pgcrypto/pgp-s2k.c
View file @
35c675a7
...
...
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.
2 2005/07/11 15:07:59
tgl Exp $
* $PostgreSQL: pgsql/contrib/pgcrypto/pgp-s2k.c,v 1.
3 2005/07/18 17:12:54
tgl Exp $
*/
#include "postgres.h"
...
...
@@ -225,13 +225,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode,int digest_algo)
case
0
:
break
;
case
1
:
res
=
px_get_random_bytes
(
s2k
->
salt
,
PGP_S2K_SALT
);
res
=
px_get_
pseudo_
random_bytes
(
s2k
->
salt
,
PGP_S2K_SALT
);
break
;
case
3
:
res
=
px_get_random_bytes
(
s2k
->
salt
,
PGP_S2K_SALT
);
res
=
px_get_
pseudo_
random_bytes
(
s2k
->
salt
,
PGP_S2K_SALT
);
if
(
res
<
0
)
break
;
res
=
px_get_random_bytes
(
&
tmp
,
1
);
res
=
px_get_
pseudo_
random_bytes
(
&
tmp
,
1
);
if
(
res
<
0
)
break
;
s2k
->
iter
=
decide_count
(
tmp
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment