packages feed

Z-Botan-0.4.0.0: cbits/hs_botan_extra.cpp

#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
#include <botan/aead.h>
#include <HsFFI.h>
#include <string.h>

extern "C" {

using namespace Botan_FFI;

// Mem helper


uint8_t* hs_botan_allocate_memory(HsInt size){
    return (uint8_t*)Botan::allocate_memory(size, 1);
}
    
void hs_botan_deallocate_memory(uint8_t* eptr, uint8_t* ptr){
     Botan::deallocate_memory(ptr, eptr-ptr, 1);
}

////////////////////////////////////////////////////////////////////////////////
// RNG

int hs_botan_rng_add_entropy(botan_rng_t rng, const uint8_t *seed, HsInt off, HsInt len){
    return botan_rng_add_entropy(rng, seed+off, len);
}

// Block cipher
int hs_botan_block_cipher_set_key(botan_block_cipher_t bc, const uint8_t *key, HsInt key_off, HsInt key_len){
    return botan_block_cipher_set_key(bc, key+key_off, key_len);
}
int hs_botan_block_cipher_encrypt_blocks(botan_block_cipher_t bc
    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){
    return botan_block_cipher_encrypt_blocks(bc, in+off, out, blocks);
}
int hs_botan_block_cipher_decrypt_blocks(botan_block_cipher_t bc
    , const uint8_t in[], HsInt off, uint8_t out[], HsInt blocks){
    return botan_block_cipher_decrypt_blocks(bc, in+off, out, blocks);
}

// Hash
int hs_botan_hash_update(botan_hash_t hash, const uint8_t *input, HsInt off, HsInt len){
    return botan_hash_update(hash, input+off, len);
}

// Cipher Mode
int hs_botan_cipher_set_associated_data(botan_cipher_t cipher, const uint8_t* ad, HsInt ad_off, HsInt ad_len){
    return botan_cipher_set_associated_data(cipher, ad+ad_off, ad_len);
}

int hs_botan_cipher_start(botan_cipher_t cipher, const uint8_t* nonce, HsInt nonce_off, HsInt nonce_len){
    return botan_cipher_start(cipher, nonce+nonce_off, nonce_len);
}

HsInt hs_botan_cipher_output_size(botan_cipher_t cipher, HsInt input_len){
    return (HsInt)BOTAN_FFI_DO(Botan::Cipher_Mode, 
        (botan_struct<Botan::Cipher_Mode, 0xB4A2BF9C>*)cipher, c, 
            { return c.output_length((size_t)input_len) + c.update_granularity(); });
}

HsInt hs_botan_cipher_finish(botan_cipher_t cipher,
                           uint8_t* output,
                           HsInt output_len,
                           const uint8_t* input,
                           HsInt input_off,
                           HsInt input_len){
    size_t input_consumed, output_written;
    int r = botan_cipher_update(cipher, BOTAN_CIPHER_UPDATE_FLAG_FINAL, output, output_len
        , &output_written, input+input_off, input_len, &input_consumed);
    if (r < 0){
        return (HsInt)r;
    } else {
        return (HsInt)output_written;
    }
}

// Multiple Precision Integers
int hs_botan_mp_to_hex(botan_mp_t mp, char *out, HsInt off){
    return botan_mp_to_hex(mp, out+off);
}
HsInt hs_botan_mp_to_dec(botan_mp_t mp, char *out, HsInt off){
    size_t len;
    int r = botan_mp_to_str(mp, 10, out+off, &len);
    if (r >= 0) {
        return (HsInt)len+off-1;
    } else {
        return (HsInt)r;
    }
}
int hs_botan_mp_set_from_hex(botan_mp_t dest, const char *str, HsInt off, HsInt len){
    char temp[len+3];
    temp[0] = '0';
    temp[1] = 'x';
    memcpy(temp+2, str+off, len);
    temp[len+2] = 0;
    return botan_mp_set_from_str(dest, temp);

}
int hs_botan_mp_set_from_dec(botan_mp_t dest, const char *str, HsInt off, HsInt len){
    char temp[len+1];
    memcpy(temp, str+off, len);
    temp[len] = 0;
    return botan_mp_set_from_str(dest, temp);
}
int hs_botan_mp_from_bin(botan_mp_t mp, const uint8_t* vec, HsInt off, HsInt len){
    return botan_mp_from_bin(mp, vec+off, len);
}
int hs_botan_mp_to_bin(botan_mp_t mp, uint8_t* vec, HsInt off){
    return botan_mp_to_bin(mp, vec+off);
}

// KDF & PBKDF

int hs_botan_kdf(const char* algo
                ,uint8_t out[], size_t out_len
                ,const uint8_t secret[], size_t secret_len
                ,const uint8_t salt[], HsInt salt_off, HsInt salt_len
                ,const uint8_t label[], HsInt label_off, HsInt label_len){
    return botan_kdf(algo, out, out_len, secret, secret_len, salt+salt_off, salt_len, label+label_off, label_len);
}

int hs_botan_pwdhash(const char* algo
                    ,HsInt p1, HsInt p2, HsInt p3
                    ,uint8_t out[], HsInt out_len
                    ,const char* passwd, HsInt passwd_len
                    ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){
    return botan_pwdhash(algo, p1, p2, p3, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);
}

int hs_botan_pwdhash_timed(const char* algo
                          ,uint32_t msec
                          ,uint8_t out[], HsInt out_len
                          ,const char* passwd, HsInt passwd_len
                          ,const uint8_t salt[], HsInt salt_off, HsInt salt_len){
    return botan_pwdhash_timed(algo, msec, NULL, NULL, NULL, out, out_len, passwd, passwd_len, salt+salt_off, salt_len);
}

int hs_botan_bcrypt_is_valid(const char* pwd, const char* hash, HsInt hash_off, HsInt hash_len){

    char hash0[hash_len+1];
    memcpy(hash0, hash+hash_off, hash_len);
    hash0[hash_len] = 0;

    return botan_bcrypt_is_valid(pwd, hash0);
}

// MAC

int hs_botan_mac_set_key(botan_mac_t mac, const uint8_t* key, HsInt key_off, HsInt key_len){
    return botan_mac_set_key(mac, key+key_off, key_len);
}
int hs_botan_mac_update(botan_mac_t mac, const uint8_t* buf, HsInt off ,HsInt len){
    return botan_mac_update(mac, buf + off, len);
}

int hs_botan_mac_final(botan_mac_t mac, uint8_t out[]){
    return botan_mac_final(mac, out);
}
int hs_botan_mac_clear(botan_mac_t mac){
    return botan_mac_clear(mac);
}

int hs_botan_mac_name(botan_mac_t mac, char* name, size_t* name_len){
    return botan_mac_name(mac, name, name_len);
}
int hs_botan_mac_get_keyspec(botan_mac_t mac,
    size_t* out_minimum_keylength,
    size_t* out_maximum_keylength,
    size_t* out_keylength_modulo){
        return botan_mac_get_keyspec(mac, out_minimum_keylength, out_maximum_keylength, out_keylength_modulo);
}

// Public Key Creation, Import and Export

int hs_botan_privkey_load (botan_privkey_t* key, botan_rng_t rng
                          ,const uint8_t bits[], HsInt off, HsInt len
                          ,const char* passwd){
    if (*passwd == '\0') passwd = NULL;
    return botan_privkey_load(key, rng, bits+off, len, passwd);
}

int hs_botan_pubkey_load (botan_pubkey_t* key
                         ,const uint8_t bits[], HsInt off, HsInt len){
    return botan_pubkey_load(key, bits+off, len);
}

// Public Key Encryption / Decryption

int hs_botan_pk_op_encrypt(botan_pk_op_encrypt_t op, botan_rng_t rng, uint8_t out[], size_t *out_len, const uint8_t plaintext[], HsInt plaintext_off, HsInt plaintext_len){
    return botan_pk_op_encrypt(op, rng, out, out_len, plaintext+plaintext_off, plaintext_len);
}

int hs_botan_pk_op_decrypt(botan_pk_op_decrypt_t op, uint8_t out[], size_t *out_len, uint8_t ciphertext[], HsInt ciphertext_off, HsInt ciphertext_len){
    return botan_pk_op_decrypt(op, out, out_len, ciphertext+ciphertext_off, ciphertext_len);
}

// Signature Generation & Signature Verification

int hs_botan_pk_op_sign_update(botan_pk_op_sign_t op, const uint8_t in[], HsInt off, HsInt len){
    return botan_pk_op_sign_update(op, in+off, len);
}

int hs_botan_pk_op_verify_update(botan_pk_op_verify_t op, const uint8_t in[], HsInt off, HsInt len){
    return botan_pk_op_verify_update(op, in+off, len);
}

int hs_botan_pk_op_verify_finish(botan_pk_op_verify_t op, const uint8_t sig[], HsInt off, HsInt len){
    return botan_pk_op_verify_finish(op, sig+off, len);
}

// Key Agreement

int hs_botan_pk_op_key_agreement(botan_pk_op_ka_t op, uint8_t out[], size_t out_len, const uint8_t other_key[], HsInt other_key_off, HsInt other_key_len, const uint8_t salt[], HsInt salt_off, HsInt salt_len){
    // this function will not rewrite out_len
    return botan_pk_op_key_agreement(op, out, &out_len, other_key+other_key_off, other_key_len, salt+salt_off, salt_len);
}

// X.509 Certificates & Certificate Revocation Lists

int hs_botan_x509_cert_load(botan_x509_cert_t *cert_obj, const uint8_t cert[], HsInt cert_off, HsInt cert_len){
    return botan_x509_cert_load(cert_obj, cert+cert_off, cert_len);
}

int hs_botan_x509_cert_verify(botan_x509_cert_t cert
        , const botan_x509_cert_t *intermediates, HsInt intermediates_len
        , const botan_x509_cert_t *trusted, HsInt trusted_len
        , HsInt required_strength, const char *hostname, uint64_t reference_time){
    int r1;
    int r2 = botan_x509_cert_verify(&r1, cert
            , intermediates, intermediates_len
            , trusted, trusted_len
            , NULL, required_strength, hostname, reference_time);
    if (r2 < 0){
        return r2;
    } else { 
        return r1; 
    }
}

int hs_botan_x509_cert_verify_with_crl(botan_x509_cert_t cert
        , const botan_x509_cert_t *intermediates, HsInt intermediates_len
        , const botan_x509_cert_t *trusted, HsInt trusted_len
        , const botan_x509_crl_t *crls, HsInt crls_len
        , HsInt required_strength, const char *hostname, uint64_t reference_time){
    int r1;
    int r2 = botan_x509_cert_verify_with_crl(&r1, cert
            , intermediates, intermediates_len
            , trusted, trusted_len
            , crls, crls_len
            , NULL, required_strength, hostname, reference_time);
    if (r2 < 0){
        return r2;
    } else { 
        return r1; 
    }
}


int hs_botan_x509_crl_load(botan_x509_crl_t *crl_obj, const uint8_t crl[], HsInt crl_off, HsInt crl_len){
    return botan_x509_crl_load(crl_obj, crl+crl_off, crl_len);
}

// Key wrap

/**
  * Advanced Encryption Standard (AES) Key Wrap Algorithm
  * See `https://tools.ietf.org/html/rfc3394`.
  * Key wrapping as per RFC 3394
*/

int hs_botan_key_unwrap3394(const uint8_t wrapped_key[], HsInt wrapped_key_off, HsInt wrapped_key_len
                           ,const uint8_t kek[], HsInt kek_len
                           ,uint8_t key[], size_t key_len){
    return botan_key_unwrap3394(wrapped_key+wrapped_key_off, wrapped_key_len
                               ,kek, kek_len
                               ,key, &key_len);}

// OTP

int hs_botan_hotp_init(botan_hotp_t* hotp
                      ,const uint8_t key[], HsInt key_off, HsInt key_len
                      ,const char* hash_algo
                      ,HsInt digits){
    return botan_hotp_init(hotp
                          ,key+key_off, key_len
                          ,hash_algo, digits);}

int hs_botan_totp_init(botan_totp_t* totp
                      ,const uint8_t key[], HsInt key_off, HsInt key_len
                      ,const char* hash_algo
                      ,HsInt digits
                      ,HsInt time_step){
    return botan_totp_init(totp, key+key_off, key_len, hash_algo, digits, time_step);}

// FPE

int hs_botan_fpe_fe1_init(botan_fpe_t* fpe, botan_mp_t n,
                       const uint8_t key[], HsInt key_off, HsInt key_len,
                       size_t rounds, uint32_t flags){
return botan_fpe_fe1_init(fpe, n,
                       key+key_off, key_len,
                       rounds, flags);}

int hs_botan_fpe_encrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)
{return botan_fpe_encrypt(fpe, x, tweak+tweak_off, tweak_len);}

int hs_botan_fpe_decrypt(botan_fpe_t fpe, botan_mp_t x, const uint8_t tweak[], HsInt tweak_off, HsInt tweak_len)
{return botan_fpe_decrypt(fpe, x, tweak+tweak_off, tweak_len);}

}