Beispiel #1
0
/* The DTLS Generate Cookie callback
 *  return : number of bytes copied into buf, or error
 */
int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx)
{
    int sd = ssl->wfd;
    struct sockaddr_storage peer;
    XSOCKLENT peerSz = sizeof(peer);
    Sha sha;
    byte digest[SHA_DIGEST_SIZE];
    int  ret = 0;

    (void)ctx;

    XMEMSET(&peer, 0, sizeof(peer));
    if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) {
        CYASSL_MSG("getpeername failed in EmbedGenerateCookie");
        return GEN_COOKIE_E;
    }
    
    ret = InitSha(&sha);
    if (ret != 0)
        return ret;
    ShaUpdate(&sha, (byte*)&peer, peerSz);
    ShaFinal(&sha, digest);

    if (sz > SHA_DIGEST_SIZE)
        sz = SHA_DIGEST_SIZE;
    XMEMCPY(buf, digest, sz);

    return sz;
}
Beispiel #2
0
void bench_sha(void)
{
    Sha    hash;
    byte   digest[SHA_DIGEST_SIZE];
    double start, total, persec;
    int    i, ret;
        
    ret = InitSha(&hash);
    if (ret != 0) {
        printf("InitSha failed, ret = %d\n", ret);
        return;
    }
    start = current_time(1);
    
    for(i = 0; i < numBlocks; i++)
        ShaUpdate(&hash, plain, sizeof(plain));
   
    ShaFinal(&hash, digest);

    total = current_time(0) - start;
    persec = 1 / total * numBlocks;
#ifdef BENCH_EMBEDDED
    /* since using kB, convert to MB/s */
    persec = persec / 1024;
#endif

    printf("SHA      %d %s took %5.3f seconds, %7.3f MB/s\n", numBlocks,
                                              blockType, total, persec);
}
/* The DTLS Generate Cookie callback
 *  return : number of bytes copied into buf, or error
 */
int EmbedGenerateCookie(byte *buf, int sz, void *ctx)
{
    CYASSL* ssl = (CYASSL*)ctx;
    int sd = ssl->wfd;
    struct sockaddr_storage peer;
    socklen_t peerSz = sizeof(peer);
    byte cookieSrc[sizeof(struct in6_addr) + sizeof(int)];
    int cookieSrcSz = 0;
    Sha sha;

    getpeername(sd, (struct sockaddr*)&peer, &peerSz);
    
    if (peer.ss_family == AF_INET) {
        struct sockaddr_in *s = (struct sockaddr_in*)&peer;

        cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port);
        XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port));
        XMEMCPY(cookieSrc + sizeof(s->sin_port),
                                     &s->sin_addr, sizeof(struct in_addr));
    }
    else if (peer.ss_family == AF_INET6) {
        struct sockaddr_in6 *s = (struct sockaddr_in6*)&peer;

        cookieSrcSz = sizeof(struct in6_addr) + sizeof(s->sin6_port);
        XMEMCPY(cookieSrc, &s->sin6_port, sizeof(s->sin6_port));
        XMEMCPY(cookieSrc + sizeof(s->sin6_port),
                                    &s->sin6_addr, sizeof(struct in6_addr));
    }

    InitSha(&sha);
    ShaUpdate(&sha, cookieSrc, cookieSrcSz);
    ShaFinal(&sha, buf);

    return SHA_DIGEST_SIZE;
}
Beispiel #4
0
int ShaHash(const byte* data, word32 len, byte* hash)
{
    int ret = 0;
#ifdef CYASSL_SMALL_STACK
    Sha* sha;
#else
    Sha sha[1];
#endif

#ifdef CYASSL_SMALL_STACK
    sha = (Sha*)XMALLOC(sizeof(Sha), NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (sha == NULL)
        return MEMORY_E;
#endif

    if ((ret = InitSha(sha)) != 0) {
        CYASSL_MSG("InitSha failed");
    }
    else {
        ShaUpdate(sha, data, len);
        ShaFinal(sha, hash);
    }

#ifdef CYASSL_SMALL_STACK
    XFREE(sha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}
Beispiel #5
0
    void ShaFinal(Sha* sha, byte* hash)
    {
        __IO uint16_t nbvalidbitsdata = 0;
        
        /* finish reading any trailing bytes into FIFO */
        if (sha->buffLen) {
            HASH_DataIn(*(uint32_t*)sha->buffer);
            sha->loLen += sha->buffLen;
        }

        /* calculate number of valid bits in last word of input data */
        nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE);

        /* configure number of valid bits in last word of the data */
        HASH_SetLastWordValidBitsNbr(nbvalidbitsdata);

        /* start HASH processor */
        HASH_StartDigest();

        /* wait until Busy flag == RESET */
        while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {}

        /* read message digest */
        sha->digest[0] = HASH->HR[0];
        sha->digest[1] = HASH->HR[1];
        sha->digest[2] = HASH->HR[2];
        sha->digest[3] = HASH->HR[3];
        sha->digest[4] = HASH->HR[4];
        
        ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);

        XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);

        InitSha(sha);  /* reset state */
    }
Beispiel #6
0
/* check mcapi sha against internal */
static int check_sha(void)
{
    CRYPT_SHA_CTX mcSha;
    Sha           defSha;
    int           ret = 0;
    byte          mcDigest[CRYPT_SHA_DIGEST_SIZE];
    byte          defDigest[SHA_DIGEST_SIZE];

    CRYPT_SHA_Initialize(&mcSha);
    ret = InitSha(&defSha);
    if (ret != 0) {
        printf("sha init default failed\n");
        return -1;
    }

    CRYPT_SHA_DataAdd(&mcSha, ourData, OUR_DATA_SIZE);
    ShaUpdate(&defSha, ourData, OUR_DATA_SIZE);

    CRYPT_SHA_Finalize(&mcSha, mcDigest);
    ShaFinal(&defSha, defDigest);

    if (memcmp(mcDigest, defDigest, CRYPT_SHA_DIGEST_SIZE) != 0) {
        printf("sha final memcmp failed\n");
        return -1;
    } 
    printf("sha         mcapi test passed\n");

    return 0;
}
Beispiel #7
0
int sha_test(void)
{
    Sha  sha;
    byte hash[SHA_DIGEST_SIZE];

    testVector a, b, c, d;
    testVector test_sha[4];
    int ret   = 0;
    int times = sizeof(test_sha) / sizeof(struct testVector), i;

    a.input  = "abc";
    a.output = "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2"
               "\x6C\x9C\xD0\xD8\x9D";
    a.inLen  = strlen(a.input);
    a.outLen = strlen(a.output);

    b.input  = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    b.output = "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29"
               "\xE5\xE5\x46\x70\xF1";
    b.inLen  = strlen(b.input);
    b.outLen = strlen(b.output);

    c.input  = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
               "aaaaaa";
    c.output = "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44"
               "\x2A\x25\xEC\x64\x4D";
    c.inLen  = strlen(c.input);
    c.outLen = strlen(c.output);

    d.input  = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
               "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
               "aaaaaaaaaa";
    d.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7"
               "\x53\x99\x5E\x26\xA0";
    d.inLen  = strlen(d.input);
    d.outLen = strlen(d.output);

    test_sha[0] = a;
    test_sha[1] = b;
    test_sha[2] = c;
    test_sha[3] = d;

    ret = InitSha(&sha);
    if (ret != 0)
        return ret;

    for (i = 0; i < times; ++i) {
        ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen);
        ShaFinal(&sha, hash);

        if (memcmp(hash, test_sha[i].output, SHA_DIGEST_SIZE) != 0)
            return -10 - i;
    }

    return 0;
}
Beispiel #8
0
/* Initialize SHA */
int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha)
{
    typedef char sha_test[sizeof(CRYPT_SHA_CTX) >= sizeof(Sha) ? 1 : -1];
    (void)sizeof(sha_test);

    if (sha == NULL)
        return BAD_FUNC_ARG;

    return InitSha((Sha*)sha);
}
Beispiel #9
0
tr_sha1_ctx_t
tr_sha1_init (void)
{
  Sha * handle = tr_new (Sha, 1);

  if (check_result (InitSha (handle)))
    return handle;

  tr_free (handle);
  return NULL;
}
Beispiel #10
0
static int InitHmac(Hmac* hmac, int type)
{
    int ret = 0;

    hmac->innerHashKeyed = 0;
    hmac->macType = (byte)type;

    if (!(type == MD5 || type == SHA    || type == SHA256 || type == SHA384
                      || type == SHA512 || type == BLAKE2B_ID))
        return BAD_FUNC_ARG;

    switch (type) {
        #ifndef NO_MD5
        case MD5:
            InitMd5(&hmac->hash.md5);
        break;
        #endif

        #ifndef NO_SHA
        case SHA:
            ret = InitSha(&hmac->hash.sha);
        break;
        #endif
        
        #ifndef NO_SHA256
        case SHA256:
            ret = InitSha256(&hmac->hash.sha256);
        break;
        #endif
        
        #ifdef CYASSL_SHA384
        case SHA384:
            ret = InitSha384(&hmac->hash.sha384);
        break;
        #endif
        
        #ifdef CYASSL_SHA512
        case SHA512:
            ret = InitSha512(&hmac->hash.sha512);
        break;
        #endif
        
        #ifdef HAVE_BLAKE2 
        case BLAKE2B_ID:
            ret = InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256);
        break;
        #endif
        
        default:
            return BAD_FUNC_ARG;
    }

    return ret;
}
Beispiel #11
0
/* Create and store the master secret see page 32, 6.1 */
int MakeMasterSecret(SSL* ssl)
{
    byte   shaOutput[SHA_DIGEST_SIZE];
    byte   md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
    byte   shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
    int    i;
    word32 idx;
    word32 pmsSz = ssl->arrays.preMasterSz;

    Md5 md5;
    Sha sha;

#ifndef NO_TLS
    if (ssl->options.tls) return MakeTlsMasterSecret(ssl);
#endif

    InitMd5(&md5);
    InitSha(&sha);

    memcpy(md5Input, ssl->arrays.preMasterSecret, pmsSz);

    for (i = 0; i < MASTER_ROUNDS; ++i) {
        byte prefix[PREFIX];
        if (!SetPrefix(prefix, i)) {
            return PREFIX_ERROR;
        }

        idx = 0;
        memcpy(shaInput, prefix, i + 1);
        idx += i + 1;

        memcpy(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz);
        idx += pmsSz;
        memcpy(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN);
        idx += RAN_LEN;
        memcpy(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN);
        idx += RAN_LEN;
        ShaUpdate(&sha, shaInput, idx);
        ShaFinal(&sha, shaOutput);

        idx = pmsSz;  /* preSz */
        memcpy(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
        idx += SHA_DIGEST_SIZE;
        Md5Update(&md5, md5Input, idx);
        Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]);
    }
    DeriveKeys(ssl);

    CleanPreMaster(ssl);

    return 0;
}
Beispiel #12
0
int ShaFinal(Sha* sha, byte* hash)
{
    byte* local = (byte*)sha->buffer;

    AddLength(sha, sha->buffLen);  /* before adding pads */

    local[sha->buffLen++] = 0x80;  /* add 1 */

    /* pad with zeros */
    if (sha->buffLen > SHA_PAD_SIZE) {
        XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
        sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;

        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
            ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
        #endif
        XTRANSFORM(sha, local);
        sha->buffLen = 0;
    }
    XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
   
    /* put lengths in bits */
    sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + 
                 (sha->hiLen << 3);
    sha->loLen = sha->loLen << 3;

    /* store lengths */
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU)
        ByteReverseWords(sha->buffer, sha->buffer, SHA_BLOCK_SIZE);
    #endif
    /* ! length ordering dependent on digest endian type ! */
    XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
    XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));

    #ifdef FREESCALE_MMCAU
        /* Kinetis requires only these bytes reversed */
        ByteReverseWords(&sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
                         &sha->buffer[SHA_PAD_SIZE/sizeof(word32)],
                         2 * sizeof(word32));
    #endif

    XTRANSFORM(sha, local);
    #ifdef LITTLE_ENDIAN_ORDER
        ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
    #endif
    XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);

    return InitSha(sha);  /* reset state */
}
Beispiel #13
0
int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
           int sLen, int iterations, int kLen, int hashType)
{
    Md5  md5;
    Sha  sha;
    int  hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE;
    int  i, ret = 0;
    byte buffer[SHA_DIGEST_SIZE];  /* max size */

    if (hashType != MD5 && hashType != SHA)
        return BAD_FUNC_ARG;

    if (kLen > hLen)
        return BAD_FUNC_ARG;

    if (iterations < 1)
        return BAD_FUNC_ARG;

    if (hashType == MD5) {
        InitMd5(&md5);
        Md5Update(&md5, passwd, pLen);
        Md5Update(&md5, salt,   sLen);
        Md5Final(&md5,  buffer);
    }
    else {
        ret = InitSha(&sha);
        if (ret != 0)
            return ret;
        ShaUpdate(&sha, passwd, pLen);
        ShaUpdate(&sha, salt,   sLen);
        ShaFinal(&sha,  buffer);
    }

    for (i = 1; i < iterations; i++) {
        if (hashType == MD5) {
            Md5Update(&md5, buffer, hLen);
            Md5Final(&md5,  buffer);
        }
        else {
            ShaUpdate(&sha, buffer, hLen);
            ShaFinal(&sha,  buffer);
        }
    }
    XMEMCPY(output, buffer, kLen);

    return 0;
}
Beispiel #14
0
int DeriveKeys(SSL* ssl)
{
    int length = 2 * ssl->specs.hash_size + 
                 2 * ssl->specs.key_size  +
                 2 * ssl->specs.iv_size;
    int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i;

    byte shaOutput[SHA_DIGEST_SIZE];
    byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE];
    byte shaInput[KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN];
  
    Md5 md5;
    Sha sha;

    byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE];  /* max size */

    InitMd5(&md5);
    InitSha(&sha);

    XMEMCPY(md5Input, ssl->arrays.masterSecret, SECRET_LEN);

    for (i = 0; i < rounds; ++i) {
        int j   = i + 1;
        int idx = j;

        if (!SetPrefix(shaInput, i)) {
            return PREFIX_ERROR;
        }

        XMEMCPY(shaInput + idx, ssl->arrays.masterSecret, SECRET_LEN);
        idx += SECRET_LEN;
        XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN);
        idx += RAN_LEN;
        XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN);
        idx += RAN_LEN;

        ShaUpdate(&sha, shaInput, sizeof(shaInput) - KEY_PREFIX + j);
        ShaFinal(&sha, shaOutput);

        XMEMCPY(&md5Input[SECRET_LEN], shaOutput, SHA_DIGEST_SIZE);
        Md5Update(&md5, md5Input, sizeof(md5Input));
        Md5Final(&md5, keyData + i * MD5_DIGEST_SIZE);
    }

    return StoreKeys(ssl, keyData);
}
Beispiel #15
0
static int InitHmac(Hmac* hmac, int type)
{
    hmac->innerHashKeyed = 0;
    hmac->macType = (byte)type;

    if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384
                      || type == SHA512))
        return BAD_FUNC_ARG;

    switch (type) {
        #ifndef NO_MD5
        case MD5:
            InitMd5(&hmac->hash.md5);
        break;
        #endif

        #ifndef NO_SHA
        case SHA:
            InitSha(&hmac->hash.sha);
        break;
        #endif
        
        #ifndef NO_SHA256
        case SHA256:
            InitSha256(&hmac->hash.sha256);
        break;
        #endif
        
        #ifdef CYASSL_SHA384
        case SHA384:
            InitSha384(&hmac->hash.sha384);
        break;
        #endif
        
        #ifdef CYASSL_SHA512
        case SHA512:
            InitSha512(&hmac->hash.sha512);
        break;
        #endif
        
        default:
        break;
    }

    return 0;
}
Beispiel #16
0
static int InitHmac(Hmac* hmac, int type)
{
    hmac->innerHashKeyed = 0;
    hmac->macType = (byte)type;

    if (!(type == MD5 || type == SHA || type == SHA256))
        return BAD_FUNC_ARG;

    if (type == MD5)
        InitMd5(&hmac->hash.md5);
    else if (type == SHA)
        InitSha(&hmac->hash.sha);
#ifndef NO_SHA256
    else if (type == SHA256)
        InitSha256(&hmac->hash.sha256);
#endif

    return 0;
}
Beispiel #17
0
void ShaFinal(Sha* sha, byte* hash)
{
    byte* local = (byte*)sha->buffer;

    AddLength(sha, sha->buffLen);               /* before adding pads */

    local[sha->buffLen++] = 0x80;  /* add 1 */

    /* pad with zeros */
    if (sha->buffLen > SHA_PAD_SIZE) {
        XMEMSET(&local[sha->buffLen], 0, SHA_BLOCK_SIZE - sha->buffLen);
        sha->buffLen += SHA_BLOCK_SIZE - sha->buffLen;

        #ifdef LITTLE_ENDIAN_ORDER
            ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
        #endif
        Transform(sha);
        sha->buffLen = 0;
    }
    XMEMSET(&local[sha->buffLen], 0, SHA_PAD_SIZE - sha->buffLen);
   
    /* put lengths in bits */
    sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + 
                 (sha->hiLen << 3);
    sha->loLen = sha->loLen << 3;

    /* store lengths */
    #ifdef LITTLE_ENDIAN_ORDER
        ByteReverseBytes(local, local, SHA_BLOCK_SIZE);
    #endif
    /* ! length ordering dependent on digest endian type ! */
    XMEMCPY(&local[SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
    XMEMCPY(&local[SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));

    Transform(sha);
    #ifdef LITTLE_ENDIAN_ORDER
        ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE);
    #endif
    XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE);

    InitSha(sha);  /* reset state */
}
Beispiel #18
0
int dsa_test()
{
    int    ret, answer;
    word32 bytes;
    word32 idx = 0;
    byte   tmp[1024];
    DsaKey key;
    RNG    rng;
    FILE*  file = fopen(dsaKey, "rb");
    Sha    sha;
    byte   hash[SHA_DIGEST_SIZE];
    byte   signature[40];

    if (!file)
        return -60;

    bytes = (word32) fread(tmp, 1, sizeof(tmp), file);
  
    InitSha(&sha);
    ShaUpdate(&sha, tmp, bytes);
    ShaFinal(&sha, hash);

    InitDsaKey(&key);
    ret = DsaPrivateKeyDecode(tmp, &idx, &key, bytes);
    if (ret != 0) return -61;

    ret = InitRng(&rng);
    if (ret != 0) return -62;

    ret = DsaSign(hash, signature, &key, &rng);
    if (ret != 0) return -63;

    ret = DsaVerify(hash, signature, &key, &answer);
    if (ret != 0) return -64;
    if (answer != 1) return -65;
    
    FreeDsaKey(&key);
    fclose(file);
    
    return 0;
}
Beispiel #19
0
void bench_sha(void)
{
    Sha    hash;
    byte   digest[SHA_DIGEST_SIZE];
    double start, total, persec;
    int    i;

    InitSha(&hash);
    start = current_time();

    for(i = 0; i < megs; i++)
        ShaUpdate(&hash, plain, sizeof(plain));

    ShaFinal(&hash, digest);

    total = current_time() - start;
    persec = 1 / total * megs;

    printf("SHA      %d megs took %5.3f seconds, %6.2f MB/s\n", megs, total,
           persec);
}
Beispiel #20
0
/* The DTLS Generate Cookie callback
 *  return : number of bytes copied into buf, or error
 */
int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx)
{
    int sd = ssl->wfd;
    struct sockaddr_in peer;
    XSOCKLENT peerSz = sizeof(peer);
    byte cookieSrc[sizeof(struct in_addr) + sizeof(int)];
    int cookieSrcSz = 0;
    Sha sha;

    (void)ctx;

    if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) {
        CYASSL_MSG("getpeername failed in EmbedGenerateCookie");
        return GEN_COOKIE_E;
    }
    
    if (peer.sin_family == AF_INET) {
        struct sockaddr_in *s = (struct sockaddr_in*)&peer;

        cookieSrcSz = sizeof(struct in_addr) + sizeof(s->sin_port);
        XMEMCPY(cookieSrc, &s->sin_port, sizeof(s->sin_port));
        XMEMCPY(cookieSrc + sizeof(s->sin_port),
                                     &s->sin_addr, sizeof(struct in_addr));
    }

    InitSha(&sha);
    ShaUpdate(&sha, cookieSrc, cookieSrcSz);

    if (sz < SHA_DIGEST_SIZE) {
        byte digest[SHA_DIGEST_SIZE];
        ShaFinal(&sha, digest);
        XMEMCPY(buf, digest, sz);
        return sz;
    }

    ShaFinal(&sha, buf);

    return SHA_DIGEST_SIZE;
}
Beispiel #21
0
/*
 * k5_sha1_hash: Hash data buffer using SHA1.
 * 
 * @data     Input data structure
 * @num_data Number of blocks
 * @output   Output data structure
 *
 * Returns 0 on success, krb5_error_code on error
 */
static krb5_error_code
k5_sha1_hash(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
{
    Sha sha;
    unsigned int i;

    if (output->length != SHA_DIGEST_SIZE)
        return(KRB5_CRYPTO_INTERNAL);

    InitSha(&sha);
    for (i = 0; i < num_data; i++) {
        const krb5_crypto_iov *iov = &data[i];

        if (SIGN_IOV(iov)) {
            ShaUpdate(&sha, (unsigned char *) iov->data.data, 
                      iov->data.length);
        }
    }
    ShaFinal(&sha, (unsigned char *) output->data);

    return(0);
}
Beispiel #22
0
/* The DTLS Generate Cookie callback
 *  return : number of bytes copied into buf, or error
 */
int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx)
{
    int sd = ssl->wfd;
    struct sockaddr_in6 peer;
    XSOCKLENT peerSz = sizeof(peer);
    Sha sha;
    byte digest[SHA_DIGEST_SIZE];

    (void)ctx;

    if (getpeername(sd, (struct sockaddr*)&peer, &peerSz) != 0) {
        CYASSL_MSG("getpeername failed in EmbedGenerateCookie");
        return GEN_COOKIE_E;
    }
    
    InitSha(&sha);

    if (peer.sin6_family == AF_INET6) {
        ShaUpdate(&sha, (byte*)&peer.sin6_port, sizeof(peer.sin6_port));
        ShaUpdate(&sha, (byte*)&peer.sin6_addr, sizeof(peer.sin6_addr));
    }
    else if (peer.sin6_family == AF_INET) {
        struct sockaddr_in *s = (struct sockaddr_in*)&peer;
        ShaUpdate(&sha, (byte*)&s->sin_port, sizeof(s->sin_port));
        ShaUpdate(&sha, (byte*)&s->sin_addr, sizeof(s->sin_addr));
    }
    else {
        CYASSL_MSG("peer sin_family unknown type in EmbedGenerateCookie");
        return GEN_COOKIE_E;
    }

    ShaFinal(&sha, digest);

    if (sz > SHA_DIGEST_SIZE)
        sz = SHA_DIGEST_SIZE;
    XMEMCPY(buf, digest, sz);

    return sz;
}
Beispiel #23
0
static int capwap_crypt_createcookie(CYASSL* ssl, unsigned char* buffer, int size, void* context) {
	int length;
	unsigned char temp[32];
    Sha sha;
    byte digest[SHA_DIGEST_SIZE];
	struct capwap_dtls* dtls = (struct capwap_dtls*)context;

	if (size != SHA_DIGEST_SIZE) {
		return -1;
	}

	/* Create buffer with peer's address and port */
	if (dtls->peeraddr.ss.ss_family == AF_INET) {
		length = sizeof(struct in_addr) + sizeof(in_port_t);
		memcpy(temp, &dtls->peeraddr.sin.sin_port, sizeof(in_port_t));
		memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin.sin_addr, sizeof(struct in_addr));
	} else if (dtls->peeraddr.ss.ss_family == AF_INET6) {
		length = sizeof(struct in6_addr) + sizeof(in_port_t);
		memcpy(temp, &dtls->peeraddr.sin6.sin6_port, sizeof(in_port_t));
		memcpy(temp + sizeof(in_port_t), &dtls->peeraddr.sin6.sin6_addr, sizeof(struct in6_addr));
	} else {
		return -1;
	}

	/* */
	if (InitSha(&sha)) {
		return -1;
	}

	ShaUpdate(&sha, temp, length);
	ShaFinal(&sha, digest);

	/* */
	memcpy(buffer, digest, SHA_DIGEST_SIZE);
	return SHA_DIGEST_SIZE;
}
Beispiel #24
0
int SHA1_Init(SHA_CTX *sha) {
	InitSha(sha);
	return 1;
}
Beispiel #25
0
/* Create and store the master secret see page 32, 6.1 */
int MakeMasterSecret(SSL* ssl)
{
    byte   shaOutput[SHA_DIGEST_SIZE];
    byte   md5Input[ENCRYPT_LEN + SHA_DIGEST_SIZE];
    byte   shaInput[PREFIX + ENCRYPT_LEN + 2 * RAN_LEN];
    int    i, ret;
    word32 idx;
    word32 pmsSz = ssl->arrays.preMasterSz;

    Md5 md5;
    Sha sha;

#ifdef SHOW_SECRETS
    {
        int j;
        printf("pre master secret: ");
        for (j = 0; j < pmsSz; j++)
            printf("%02x", ssl->arrays.preMasterSecret[j]);
        printf("\n");
    }
#endif

#ifndef NO_TLS
    if (ssl->options.tls) return MakeTlsMasterSecret(ssl);
#endif

    InitMd5(&md5);
    InitSha(&sha);

    XMEMCPY(md5Input, ssl->arrays.preMasterSecret, pmsSz);

    for (i = 0; i < MASTER_ROUNDS; ++i) {
        byte prefix[PREFIX];
        if (!SetPrefix(prefix, i)) {
            return PREFIX_ERROR;
        }

        idx = 0;
        XMEMCPY(shaInput, prefix, i + 1);
        idx += i + 1;

        XMEMCPY(shaInput + idx, ssl->arrays.preMasterSecret, pmsSz);
        idx += pmsSz;
        XMEMCPY(shaInput + idx, ssl->arrays.clientRandom, RAN_LEN);
        idx += RAN_LEN;
        XMEMCPY(shaInput + idx, ssl->arrays.serverRandom, RAN_LEN);
        idx += RAN_LEN;
        ShaUpdate(&sha, shaInput, idx);
        ShaFinal(&sha, shaOutput);

        idx = pmsSz;  /* preSz */
        XMEMCPY(md5Input + idx, shaOutput, SHA_DIGEST_SIZE);
        idx += SHA_DIGEST_SIZE;
        Md5Update(&md5, md5Input, idx);
        Md5Final(&md5, &ssl->arrays.masterSecret[i * MD5_DIGEST_SIZE]);
    }

#ifdef SHOW_SECRETS
    {
        int i;
        printf("master secret: ");
        for (i = 0; i < SECRET_LEN; i++)
            printf("%02x", ssl->arrays.masterSecret[i]);
        printf("\n");
    }
#endif

    ret = DeriveKeys(ssl);
    CleanPreMaster(ssl);

    return ret;
}
Beispiel #26
0
/* build PKCS#7 signedData content type */
int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz)
{
    static const byte outerOid[] =
        { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
                         0x07, 0x02 };
    static const byte innerOid[] =
        { ASN_OBJECT_ID, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01,
                         0x07, 0x01 };

    ESD esd;
    word32 signerInfoSz = 0;
    word32 totalSz = 0;
    int idx = 0, ret = 0;
    byte* flatSignedAttribs = NULL;
    word32 flatSignedAttribsSz = 0;
    word32 innerOidSz = sizeof(innerOid);
    word32 outerOidSz = sizeof(outerOid);

    if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
        pkcs7->encryptOID == 0 || pkcs7->hashOID == 0 || pkcs7->rng == 0 ||
        pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0 ||
        pkcs7->privateKey == NULL || pkcs7->privateKeySz == 0 ||
        output == NULL || outputSz == 0)
        return BAD_FUNC_ARG;

    XMEMSET(&esd, 0, sizeof(esd));
    ret = InitSha(&esd.sha);
    if (ret != 0)
        return ret;

    if (pkcs7->contentSz != 0)
    {
        ShaUpdate(&esd.sha, pkcs7->content, pkcs7->contentSz);
        esd.contentDigest[0] = ASN_OCTET_STRING;
        esd.contentDigest[1] = SHA_DIGEST_SIZE;
        ShaFinal(&esd.sha, &esd.contentDigest[2]);
    }

    esd.innerOctetsSz = SetOctetString(pkcs7->contentSz, esd.innerOctets);
    esd.innerContSeqSz = SetExplicit(0, esd.innerOctetsSz + pkcs7->contentSz,
                                esd.innerContSeq);
    esd.contentInfoSeqSz = SetSequence(pkcs7->contentSz + esd.innerOctetsSz +
                                    innerOidSz + esd.innerContSeqSz,
                                    esd.contentInfoSeq);

    esd.issuerSnSz = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz,
                                     esd.issuerSn);
    signerInfoSz += esd.issuerSnSz;
    esd.issuerNameSz = SetSequence(pkcs7->issuerSz, esd.issuerName);
    signerInfoSz += esd.issuerNameSz + pkcs7->issuerSz;
    esd.issuerSnSeqSz = SetSequence(signerInfoSz, esd.issuerSnSeq);
    signerInfoSz += esd.issuerSnSeqSz;
    esd.signerVersionSz = SetMyVersion(1, esd.signerVersion, 0);
    signerInfoSz += esd.signerVersionSz;
    esd.signerDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.signerDigAlgoId,
                                      hashType, 0);
    signerInfoSz += esd.signerDigAlgoIdSz;
    esd.digEncAlgoIdSz = SetAlgoID(pkcs7->encryptOID, esd.digEncAlgoId,
                                   keyType, 0);
    signerInfoSz += esd.digEncAlgoIdSz;

    if (pkcs7->signedAttribsSz != 0) {
        byte contentTypeOid[] =
                { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01,
                                 0x09, 0x03 };
        byte contentType[] =
                { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
                                 0x07, 0x01 };
        byte messageDigestOid[] =
                { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
                                 0x09, 0x04 };

        PKCS7Attrib cannedAttribs[2] =
        {
            { contentTypeOid, sizeof(contentTypeOid),
                             contentType, sizeof(contentType) },
            { messageDigestOid, sizeof(messageDigestOid),
                             esd.contentDigest, sizeof(esd.contentDigest) }
        };
        word32 cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);

        esd.signedAttribsCount += cannedAttribsCount;
        esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[0], 2,
                                             cannedAttribs, cannedAttribsCount);

        esd.signedAttribsCount += pkcs7->signedAttribsSz;
        esd.signedAttribsSz += EncodeAttributes(&esd.signedAttribs[2], 4,
                                  pkcs7->signedAttribs, pkcs7->signedAttribsSz);

        flatSignedAttribs = (byte*)XMALLOC(esd.signedAttribsSz, 0, NULL);
        flatSignedAttribsSz = esd.signedAttribsSz;
        if (flatSignedAttribs == NULL)
            return MEMORY_E;
        FlattenAttributes(flatSignedAttribs,
                                     esd.signedAttribs, esd.signedAttribsCount);
        esd.signedAttribSetSz = SetImplicit(ASN_SET, 0, esd.signedAttribsSz,
                                                           esd.signedAttribSet);
    }
    /* Calculate the final hash and encrypt it. */
    {
        RsaKey privKey;
        int result;
        word32 scratch = 0;

        byte digestInfo[MAX_SEQ_SZ + MAX_ALGO_SZ +
                        MAX_OCTET_STR_SZ + SHA_DIGEST_SIZE];
        byte digestInfoSeq[MAX_SEQ_SZ];
        byte digestStr[MAX_OCTET_STR_SZ];
        word32 digestInfoSeqSz, digestStrSz;
        int digIdx = 0;

        if (pkcs7->signedAttribsSz != 0) {
            byte attribSet[MAX_SET_SZ];
            word32 attribSetSz;

            attribSetSz = SetSet(flatSignedAttribsSz, attribSet);

            ret = InitSha(&esd.sha);
            if (ret < 0) {
                XFREE(flatSignedAttribs, 0, NULL);
                return ret;
            }
            ShaUpdate(&esd.sha, attribSet, attribSetSz);
            ShaUpdate(&esd.sha, flatSignedAttribs, flatSignedAttribsSz);
        }
        ShaFinal(&esd.sha, esd.contentAttribsDigest);

        digestStrSz = SetOctetString(SHA_DIGEST_SIZE, digestStr);
        digestInfoSeqSz = SetSequence(esd.signerDigAlgoIdSz +
                                      digestStrSz + SHA_DIGEST_SIZE,
                                      digestInfoSeq);

        XMEMCPY(digestInfo + digIdx, digestInfoSeq, digestInfoSeqSz);
        digIdx += digestInfoSeqSz;
        XMEMCPY(digestInfo + digIdx,
                                    esd.signerDigAlgoId, esd.signerDigAlgoIdSz);
        digIdx += esd.signerDigAlgoIdSz;
        XMEMCPY(digestInfo + digIdx, digestStr, digestStrSz);
        digIdx += digestStrSz;
        XMEMCPY(digestInfo + digIdx, esd.contentAttribsDigest, SHA_DIGEST_SIZE);
        digIdx += SHA_DIGEST_SIZE;

        result = InitRsaKey(&privKey, NULL);
        if (result == 0)
            result = RsaPrivateKeyDecode(pkcs7->privateKey, &scratch, &privKey,
                                         pkcs7->privateKeySz);
        if (result < 0) {
            XFREE(flatSignedAttribs, 0, NULL);
            return PUBLIC_KEY_E;
        }
        result = RsaSSL_Sign(digestInfo, digIdx,
                             esd.encContentDigest, sizeof(esd.encContentDigest),
                             &privKey, pkcs7->rng);
        FreeRsaKey(&privKey);
        if (result < 0) {
            XFREE(flatSignedAttribs, 0, NULL);
            return result;
        }
        esd.encContentDigestSz = (word32)result;
    }
    signerInfoSz += flatSignedAttribsSz + esd.signedAttribSetSz;

    esd.signerDigestSz = SetOctetString(esd.encContentDigestSz,
                                                              esd.signerDigest);
    signerInfoSz += esd.signerDigestSz + esd.encContentDigestSz;

    esd.signerInfoSeqSz = SetSequence(signerInfoSz, esd.signerInfoSeq);
    signerInfoSz += esd.signerInfoSeqSz;
    esd.signerInfoSetSz = SetSet(signerInfoSz, esd.signerInfoSet);
    signerInfoSz += esd.signerInfoSetSz;

    esd.certsSetSz = SetImplicit(ASN_SET, 0, pkcs7->singleCertSz, esd.certsSet);

    esd.singleDigAlgoIdSz = SetAlgoID(pkcs7->hashOID, esd.singleDigAlgoId,
                                      hashType, 0);
    esd.digAlgoIdSetSz = SetSet(esd.singleDigAlgoIdSz, esd.digAlgoIdSet);


    esd.versionSz = SetMyVersion(1, esd.version, 0);

    totalSz = esd.versionSz + esd.singleDigAlgoIdSz + esd.digAlgoIdSetSz +
              esd.contentInfoSeqSz + esd.certsSetSz + pkcs7->singleCertSz +
              esd.innerOctetsSz + esd.innerContSeqSz +
              innerOidSz + pkcs7->contentSz +
              signerInfoSz;
    esd.innerSeqSz = SetSequence(totalSz, esd.innerSeq);
    totalSz += esd.innerSeqSz;
    esd.outerContentSz = SetExplicit(0, totalSz, esd.outerContent);
    totalSz += esd.outerContentSz + outerOidSz;
    esd.outerSeqSz = SetSequence(totalSz, esd.outerSeq);
    totalSz += esd.outerSeqSz;

    if (outputSz < totalSz)
        return BUFFER_E;

    idx = 0;
    XMEMCPY(output + idx, esd.outerSeq, esd.outerSeqSz);
    idx += esd.outerSeqSz;
    XMEMCPY(output + idx, outerOid, outerOidSz);
    idx += outerOidSz;
    XMEMCPY(output + idx, esd.outerContent, esd.outerContentSz);
    idx += esd.outerContentSz;
    XMEMCPY(output + idx, esd.innerSeq, esd.innerSeqSz);
    idx += esd.innerSeqSz;
    XMEMCPY(output + idx, esd.version, esd.versionSz);
    idx += esd.versionSz;
    XMEMCPY(output + idx, esd.digAlgoIdSet, esd.digAlgoIdSetSz);
    idx += esd.digAlgoIdSetSz;
    XMEMCPY(output + idx, esd.singleDigAlgoId, esd.singleDigAlgoIdSz);
    idx += esd.singleDigAlgoIdSz;
    XMEMCPY(output + idx, esd.contentInfoSeq, esd.contentInfoSeqSz);
    idx += esd.contentInfoSeqSz;
    XMEMCPY(output + idx, innerOid, innerOidSz);
    idx += innerOidSz;
    XMEMCPY(output + idx, esd.innerContSeq, esd.innerContSeqSz);
    idx += esd.innerContSeqSz;
    XMEMCPY(output + idx, esd.innerOctets, esd.innerOctetsSz);
    idx += esd.innerOctetsSz;
    XMEMCPY(output + idx, pkcs7->content, pkcs7->contentSz);
    idx += pkcs7->contentSz;
    XMEMCPY(output + idx, esd.certsSet, esd.certsSetSz);
    idx += esd.certsSetSz;
    XMEMCPY(output + idx, pkcs7->singleCert, pkcs7->singleCertSz);
    idx += pkcs7->singleCertSz;
    XMEMCPY(output + idx, esd.signerInfoSet, esd.signerInfoSetSz);
    idx += esd.signerInfoSetSz;
    XMEMCPY(output + idx, esd.signerInfoSeq, esd.signerInfoSeqSz);
    idx += esd.signerInfoSeqSz;
    XMEMCPY(output + idx, esd.signerVersion, esd.signerVersionSz);
    idx += esd.signerVersionSz;
    XMEMCPY(output + idx, esd.issuerSnSeq, esd.issuerSnSeqSz);
    idx += esd.issuerSnSeqSz;
    XMEMCPY(output + idx, esd.issuerName, esd.issuerNameSz);
    idx += esd.issuerNameSz;
    XMEMCPY(output + idx, pkcs7->issuer, pkcs7->issuerSz);
    idx += pkcs7->issuerSz;
    XMEMCPY(output + idx, esd.issuerSn, esd.issuerSnSz);
    idx += esd.issuerSnSz;
    XMEMCPY(output + idx, esd.signerDigAlgoId, esd.signerDigAlgoIdSz);
    idx += esd.signerDigAlgoIdSz;

    /* SignerInfo:Attributes */
    if (pkcs7->signedAttribsSz != 0) {
        XMEMCPY(output + idx, esd.signedAttribSet, esd.signedAttribSetSz);
        idx += esd.signedAttribSetSz;
        XMEMCPY(output + idx, flatSignedAttribs, flatSignedAttribsSz);
        idx += flatSignedAttribsSz;
        XFREE(flatSignedAttribs, 0, NULL);
    }

    XMEMCPY(output + idx, esd.digEncAlgoId, esd.digEncAlgoIdSz);
    idx += esd.digEncAlgoIdSz;
    XMEMCPY(output + idx, esd.signerDigest, esd.signerDigestSz);
    idx += esd.signerDigestSz;
    XMEMCPY(output + idx, esd.encContentDigest, esd.encContentDigestSz);
    idx += esd.encContentDigestSz;

    return idx;
}
Beispiel #27
0
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
                 int saltLen, int iterations, int kLen, int hashType, int id)
{
    /* all in bytes instead of bits */
    word32 u, v, dLen, pLen, iLen, sLen, totalLen;
    int    dynamic = 0;
    int    ret = 0;
    int    i;
    byte   *D, *S, *P, *I;
#ifdef CYASSL_SMALL_STACK
    byte   staticBuffer[1]; /* force dynamic usage */
#else
    byte   staticBuffer[1024];
#endif
    byte*  buffer = staticBuffer;

#ifdef CYASSL_SMALL_STACK
    byte*  Ai;
    byte*  B;
#else
    byte   Ai[PBKDF_DIGEST_SIZE];
    byte   B[PBKDF_DIGEST_SIZE];
#endif

    if (!iterations)
        iterations = 1;

    if (hashType == MD5) {
        v = MD5_BLOCK_SIZE;
        u = MD5_DIGEST_SIZE;
    }
    else if (hashType == SHA) {
        v = SHA_BLOCK_SIZE;
        u = SHA_DIGEST_SIZE;
    }
#ifndef NO_SHA256
    else if (hashType == SHA256) {
        v = SHA256_BLOCK_SIZE;
        u = SHA256_DIGEST_SIZE;
    }
#endif
#ifdef CYASSL_SHA512
    else if (hashType == SHA512) {
        v = SHA512_BLOCK_SIZE;
        u = SHA512_DIGEST_SIZE;
    }
#endif
    else
        return BAD_FUNC_ARG;

#ifdef CYASSL_SMALL_STACK
    Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (Ai == NULL)
        return MEMORY_E;

    B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    if (B == NULL) {
        XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        return MEMORY_E;
    }
#endif

    dLen = v;
    sLen =  v * ((saltLen + v - 1) / v);
    if (passLen)
        pLen = v * ((passLen + v - 1) / v);
    else
        pLen = 0;
    iLen = sLen + pLen;

    totalLen = dLen + sLen + pLen;

    if (totalLen > sizeof(staticBuffer)) {
        buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
        if (buffer == NULL) {
#ifdef CYASSL_SMALL_STACK
            XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
            return MEMORY_E;
        }
        dynamic = 1;
    } 

    D = buffer;
    S = D + dLen;
    P = S + sLen;
    I = S;

    XMEMSET(D, id, dLen);

    for (i = 0; i < (int)sLen; i++)
        S[i] = salt[i % saltLen];
    for (i = 0; i < (int)pLen; i++)
        P[i] = passwd[i % passLen];

    while (kLen > 0) {
        word32 currentLen;
        mp_int B1;

        if (hashType == MD5) {
            Md5 md5;

            InitMd5(&md5);
            Md5Update(&md5, buffer, totalLen);
            Md5Final(&md5, Ai);

            for (i = 1; i < iterations; i++) {
                Md5Update(&md5, Ai, u);
                Md5Final(&md5, Ai);
            }
        }
        else if (hashType == SHA) {
            Sha sha;

            ret = InitSha(&sha);
            if (ret != 0)
                break;
            ShaUpdate(&sha, buffer, totalLen);
            ShaFinal(&sha, Ai);

            for (i = 1; i < iterations; i++) {
                ShaUpdate(&sha, Ai, u);
                ShaFinal(&sha, Ai);
            }
        }
#ifndef NO_SHA256
        else if (hashType == SHA256) {
            Sha256 sha256;

            ret = InitSha256(&sha256);
            if (ret != 0)
                break;

            ret = Sha256Update(&sha256, buffer, totalLen);
            if (ret != 0)
                break;

            ret = Sha256Final(&sha256, Ai);
            if (ret != 0)
                break;

            for (i = 1; i < iterations; i++) {
                ret = Sha256Update(&sha256, Ai, u);
                if (ret != 0)
                    break;

                ret = Sha256Final(&sha256, Ai);
                if (ret != 0)
                    break;
            }
        }
#endif
#ifdef CYASSL_SHA512
        else if (hashType == SHA512) {
            Sha512 sha512;

            ret = InitSha512(&sha512);
            if (ret != 0)
                break;

            ret = Sha512Update(&sha512, buffer, totalLen);
            if (ret != 0)
                break;

            ret = Sha512Final(&sha512, Ai);
            if (ret != 0)
                break;

            for (i = 1; i < iterations; i++) {
                ret = Sha512Update(&sha512, Ai, u);
                if (ret != 0)
                    break;

                ret = Sha512Final(&sha512, Ai);
                if (ret != 0)
                    break;
            }
        }
#endif

        for (i = 0; i < (int)v; i++)
            B[i] = Ai[i % u];

        if (mp_init(&B1) != MP_OKAY)
            ret = MP_INIT_E;
        else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
            ret = MP_READ_E;
        else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
            ret = MP_ADD_E;

        if (ret != 0) {
            mp_clear(&B1);
            break;
        }

        for (i = 0; i < (int)iLen; i += v) {
            int    outSz;
            mp_int i1;
            mp_int res;

            if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
                ret = MP_INIT_E;
                break;
            }
            if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
                ret = MP_READ_E;
            else if (mp_add(&i1, &B1, &res) != MP_OKAY)
                ret = MP_ADD_E;
            else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
                ret = MP_TO_E;
            else {
                if (outSz > (int)v) {
                    /* take off MSB */
                    byte  tmp[129];
                    ret = mp_to_unsigned_bin(&res, tmp);
                    XMEMCPY(I + i, tmp + 1, v);
                }
                else if (outSz < (int)v) {
                    XMEMSET(I + i, 0, v - outSz);
                    ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
                }
                else
                    ret = mp_to_unsigned_bin(&res, I + i);
            }

            mp_clear(&i1);
            mp_clear(&res);
            if (ret < 0) break;
        }

        currentLen = min(kLen, (int)u);
        XMEMCPY(output, Ai, currentLen);
        output += currentLen;
        kLen   -= currentLen;
        mp_clear(&B1);
    }

    if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);

#ifdef CYASSL_SMALL_STACK
    XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
    XFREE(B,  NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

    return ret;
}