Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

pgp-s2k.c File Reference

#include "postgres.h"
#include "px.h"
#include "mbuf.h"
#include "pgp.h"
Include dependency graph for pgp-s2k.c:

Go to the source code of this file.

Functions

static int calc_s2k_simple (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
static int calc_s2k_salted (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
static int calc_s2k_iter_salted (PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
static int decide_count (unsigned rand_byte)
int pgp_s2k_fill (PGP_S2K *s2k, int mode, int digest_algo)
int pgp_s2k_read (PullFilter *src, PGP_S2K *s2k)
int pgp_s2k_process (PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)

Function Documentation

static int calc_s2k_iter_salted ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
) [static]

Definition at line 125 of file pgp-s2k.c.

References buf, PGP_S2K::iter, PGP_S2K::key, PGP_S2K::key_len, PGP_S2K_SALT, px_md_finish, px_md_reset, px_md_result_size, px_md_update, and PGP_S2K::salt.

Referenced by pgp_s2k_process().

{
    unsigned    md_rlen;
    uint8       buf[PGP_MAX_DIGEST];
    uint8      *dst;
    unsigned    preload = 0;
    unsigned    remain,
                c,
                cval,
                curcnt,
                count;

    cval = s2k->iter;
    count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);

    md_rlen = px_md_result_size(md);

    remain = s2k->key_len;
    dst = s2k->key;
    while (remain > 0)
    {
        px_md_reset(md);

        if (preload)
        {
            memset(buf, 0, preload);
            px_md_update(md, buf, preload);
        }
        preload++;

        px_md_update(md, s2k->salt, PGP_S2K_SALT);
        px_md_update(md, key, key_len);
        curcnt = PGP_S2K_SALT + key_len;

        while (curcnt < count)
        {
            if (curcnt + PGP_S2K_SALT < count)
                c = PGP_S2K_SALT;
            else
                c = count - curcnt;
            px_md_update(md, s2k->salt, c);
            curcnt += c;

            if (curcnt + key_len < count)
                c = key_len;
            else if (curcnt < count)
                c = count - curcnt;
            else
                break;
            px_md_update(md, key, c);
            curcnt += c;
        }
        px_md_finish(md, buf);

        if (remain > md_rlen)
        {
            memcpy(dst, buf, md_rlen);
            remain -= md_rlen;
            dst += md_rlen;
        }
        else
        {
            memcpy(dst, buf, remain);
            remain = 0;
        }
    }
    return 0;
}

static int calc_s2k_salted ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
) [static]

Definition at line 82 of file pgp-s2k.c.

References buf, PGP_S2K::key, PGP_S2K::key_len, PGP_S2K_SALT, px_md_finish, px_md_reset, px_md_result_size, px_md_update, and PGP_S2K::salt.

Referenced by pgp_s2k_process().

{
    unsigned    md_rlen;
    uint8       buf[PGP_MAX_DIGEST];
    unsigned    preload = 0;
    uint8      *dst;
    unsigned    remain;

    md_rlen = px_md_result_size(md);

    dst = s2k->key;
    remain = s2k->key_len;
    while (remain > 0)
    {
        px_md_reset(md);

        if (preload > 0)
        {
            memset(buf, 0, preload);
            px_md_update(md, buf, preload);
        }
        preload++;

        px_md_update(md, s2k->salt, PGP_S2K_SALT);
        px_md_update(md, key, key_len);
        px_md_finish(md, buf);

        if (remain > md_rlen)
        {
            memcpy(dst, buf, md_rlen);
            remain -= md_rlen;
            dst += md_rlen;
        }
        else
        {
            memcpy(dst, buf, remain);
            remain = 0;
        }
    }
    return 0;
}

static int calc_s2k_simple ( PGP_S2K s2k,
PX_MD md,
const uint8 key,
unsigned  key_len 
) [static]

Definition at line 39 of file pgp-s2k.c.

References buf, PGP_S2K::key, PGP_S2K::key_len, px_md_finish, px_md_reset, px_md_result_size, and px_md_update.

Referenced by pgp_s2k_process().

{
    unsigned    md_rlen;
    uint8       buf[PGP_MAX_DIGEST];
    unsigned    preload;
    unsigned    remain;
    uint8      *dst = s2k->key;

    md_rlen = px_md_result_size(md);

    remain = s2k->key_len;
    preload = 0;
    while (remain > 0)
    {
        px_md_reset(md);

        if (preload)
        {
            memset(buf, 0, preload);
            px_md_update(md, buf, preload);
        }
        preload++;

        px_md_update(md, key, key_len);
        px_md_finish(md, buf);

        if (remain > md_rlen)
        {
            memcpy(dst, buf, md_rlen);
            dst += md_rlen;
            remain -= md_rlen;
        }
        else
        {
            memcpy(dst, buf, remain);
            remain = 0;
        }
    }
    return 0;
}

static int decide_count ( unsigned  rand_byte  )  [static]

Definition at line 204 of file pgp-s2k.c.

Referenced by pgp_s2k_fill().

{
    return 96 + (rand_byte & 0x1F);
}

int pgp_s2k_fill ( PGP_S2K s2k,
int  mode,
int  digest_algo 
)

Definition at line 210 of file pgp-s2k.c.

References decide_count(), PGP_S2K::digest_algo, PGP_S2K::iter, PGP_S2K::mode, PGP_S2K_SALT, px_get_pseudo_random_bytes(), and PGP_S2K::salt.

Referenced by init_s2k_key().

{
    int         res = 0;
    uint8       tmp;

    s2k->mode = mode;
    s2k->digest_algo = digest_algo;

    switch (s2k->mode)
    {
        case 0:
            break;
        case 1:
            res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
            break;
        case 3:
            res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
            if (res < 0)
                break;
            res = px_get_pseudo_random_bytes(&tmp, 1);
            if (res < 0)
                break;
            s2k->iter = decide_count(tmp);
            break;
        default:
            res = PXE_PGP_BAD_S2K_MODE;
    }
    return res;
}

int pgp_s2k_process ( PGP_S2K s2k,
int  cipher,
const uint8 key,
int  key_len 
)

Definition at line 267 of file pgp-s2k.c.

References calc_s2k_iter_salted(), calc_s2k_salted(), calc_s2k_simple(), PGP_S2K::digest_algo, PGP_S2K::key_len, PGP_S2K::mode, pgp_get_cipher_key_size(), pgp_load_digest(), and px_md_free.

Referenced by init_s2k_key(), parse_symenc_sesskey(), and process_secret_key().

{
    int         res;
    PX_MD      *md;

    s2k->key_len = pgp_get_cipher_key_size(cipher);
    if (s2k->key_len <= 0)
        return PXE_PGP_UNSUPPORTED_CIPHER;

    res = pgp_load_digest(s2k->digest_algo, &md);
    if (res < 0)
        return res;

    switch (s2k->mode)
    {
        case 0:
            res = calc_s2k_simple(s2k, md, key, key_len);
            break;
        case 1:
            res = calc_s2k_salted(s2k, md, key, key_len);
            break;
        case 3:
            res = calc_s2k_iter_salted(s2k, md, key, key_len);
            break;
        default:
            res = PXE_PGP_BAD_S2K_MODE;
    }
    px_md_free(md);
    return res;
}

int pgp_s2k_read ( PullFilter src,
PGP_S2K s2k 
)

Definition at line 241 of file pgp-s2k.c.

References PGP_S2K::digest_algo, GETBYTE, PGP_S2K::iter, PGP_S2K::mode, pullf_read_fixed(), and PGP_S2K::salt.

Referenced by parse_symenc_sesskey(), and process_secret_key().

{
    int         res = 0;

    GETBYTE(src, s2k->mode);
    GETBYTE(src, s2k->digest_algo);
    switch (s2k->mode)
    {
        case 0:
            break;
        case 1:
            res = pullf_read_fixed(src, 8, s2k->salt);
            break;
        case 3:
            res = pullf_read_fixed(src, 8, s2k->salt);
            if (res < 0)
                break;
            GETBYTE(src, s2k->iter);
            break;
        default:
            res = PXE_PGP_BAD_S2K_MODE;
    }
    return res;
}