Example #1
0
def crypto_box(message, nonce, pk, sk):
    """
    Encrypts and returns a message ``message`` using the secret key ``sk``,
    public key ``pk``, and the nonce ``nonce``.

    :param message: bytes
    :param nonce: bytes
    :param pk: bytes
    :param sk: bytes
    :rtype: bytes
    """
    if len(nonce) != crypto_box_NONCEBYTES:
        raise ValueError("Invalid nonce size")

    if len(pk) != crypto_box_PUBLICKEYBYTES:
        raise ValueError("Invalid public key")

    if len(sk) != crypto_box_SECRETKEYBYTES:
        raise ValueError("Invalid secret key")

    padded = (b"\x00" * crypto_box_ZEROBYTES) + message
    ciphertext = ffi.new("unsigned char[]", len(padded))

    rc = lib.crypto_box(ciphertext, padded, len(padded), nonce, pk, sk)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(ciphertext, len(padded))[crypto_box_BOXZEROBYTES:]
Example #2
0
def crypto_box_open(ciphertext, nonce, pk, sk):
    """
    Decrypts and returns an encrypted message ``ciphertext``, using the secret
    key ``sk``, public key ``pk``, and the nonce ``nonce``.

    :param ciphertext: bytes
    :param nonce: bytes
    :param pk: bytes
    :param sk: bytes
    :rtype: bytes
    """
    if len(nonce) != crypto_box_NONCEBYTES:
        raise ValueError("Invalid nonce size")

    if len(pk) != crypto_box_PUBLICKEYBYTES:
        raise ValueError("Invalid public key")

    if len(sk) != crypto_box_SECRETKEYBYTES:
        raise ValueError("Invalid secret key")

    padded = (b"\x00" * crypto_box_BOXZEROBYTES) + ciphertext
    plaintext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_box_open(plaintext, padded, len(padded), nonce, pk, sk)
    ensure(res == 0, "An error occurred trying to decrypt the message",
           raising=exc.CryptoError)

    return ffi.buffer(plaintext, len(padded))[crypto_box_ZEROBYTES:]
Example #3
0
def crypto_box_open_afternm(ciphertext, nonce, k):
    """
    Decrypts and returns the encrypted message ``ciphertext``, using the shared
    key ``k`` and the nonce ``nonce``.

    :param ciphertext: bytes
    :param nonce: bytes
    :param k: bytes
    :rtype: bytes
    """
    if len(nonce) != crypto_box_NONCEBYTES:
        raise ValueError("Invalid nonce")

    if len(k) != crypto_box_BEFORENMBYTES:
        raise ValueError("Invalid shared key")

    padded = (b"\x00" * crypto_box_BOXZEROBYTES) + ciphertext
    plaintext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_box_open_afternm(
                plaintext, padded, len(padded), nonce, k)
    ensure(res == 0, "An error occurred trying to decrypt the message",
           raising=exc.CryptoError)

    return ffi.buffer(plaintext, len(padded))[crypto_box_ZEROBYTES:]
Example #4
0
def crypto_secretbox_open(ciphertext, nonce, key):
    """
    Decrypt and returns the encrypted message ``ciphertext`` with the secret
    ``key`` and the nonce ``nonce``.

    :param ciphertext: bytes
    :param nonce: bytes
    :param key: bytes
    :rtype: bytes
    """
    if len(key) != crypto_secretbox_KEYBYTES:
        raise ValueError("Invalid key")

    if len(nonce) != crypto_secretbox_NONCEBYTES:
        raise ValueError("Invalid nonce")

    padded = b"\x00" * crypto_secretbox_BOXZEROBYTES + ciphertext
    plaintext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_secretbox_open(
               plaintext, padded, len(padded), nonce, key)
    ensure(res == 0, "Decryption failed. Ciphertext failed verification",
           raising=exc.CryptoError)

    plaintext = ffi.buffer(plaintext, len(padded))
    return plaintext[crypto_secretbox_ZEROBYTES:]
Example #5
0
def crypto_box_afternm(message, nonce, k):
    """
    Encrypts and returns the message ``message`` using the shared key ``k`` and
    the nonce ``nonce``.

    :param message: bytes
    :param nonce: bytes
    :param k: bytes
    :rtype: bytes
    """
    if len(nonce) != crypto_box_NONCEBYTES:
        raise ValueError("Invalid nonce")

    if len(k) != crypto_box_BEFORENMBYTES:
        raise ValueError("Invalid shared key")

    padded = b"\x00" * crypto_box_ZEROBYTES + message
    ciphertext = ffi.new("unsigned char[]", len(padded))

    rc = lib.crypto_box_afternm(ciphertext, padded, len(padded), nonce, k)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(ciphertext, len(padded))[crypto_box_BOXZEROBYTES:]
Example #6
0
def crypto_pwhash_scryptsalsa208sha256_str(
        passwd,
        opslimit=SCRYPT_OPSLIMIT_INTERACTIVE,
        memlimit=SCRYPT_MEMLIMIT_INTERACTIVE):
    """
    Derive a cryptographic key using the ``passwd`` and ``salt``
    given as input, returning a string representation which includes
    the salt and the tuning parameters.

    The returned string can be directly stored as a password hash.

    See :py:func:`.crypto_pwhash_scryptsalsa208sha256` for a short
    discussion about ``opslimit`` and ``memlimit`` values.

    :param bytes passwd:
    :param int opslimit:
    :param int memlimit:
    :return: serialized key hash, including salt and tuning parameters
    :rtype: bytes
    """
    buf = ffi.new("char[]", SCRYPT_STRBYTES)

    ret = lib.crypto_pwhash_scryptsalsa208sha256_str(buf, passwd, len(passwd),
                                                     opslimit, memlimit)

    ensure(ret == 0,
           'Unexpected failure in password hashing',
           raising=exc.RuntimeError)

    return ffi.string(buf)
Example #7
0
def crypto_secretbox_open(ciphertext, nonce, key):
    """
    Decrypt and returns the encrypted message ``ciphertext`` with the secret
    ``key`` and the nonce ``nonce``.

    :param ciphertext: bytes
    :param nonce: bytes
    :param key: bytes
    :rtype: bytes
    """
    if len(key) != crypto_secretbox_KEYBYTES:
        raise ValueError("Invalid key")

    if len(nonce) != crypto_secretbox_NONCEBYTES:
        raise ValueError("Invalid nonce")

    padded = b"\x00" * crypto_secretbox_BOXZEROBYTES + ciphertext
    plaintext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_secretbox_open(plaintext, padded, len(padded), nonce, key)
    ensure(res == 0,
           "Decryption failed. Ciphertext failed verification",
           raising=exc.CryptoError)

    plaintext = ffi.buffer(plaintext, len(padded))
    return plaintext[crypto_secretbox_ZEROBYTES:]
Example #8
0
def crypto_hash_sha512(message):
    """
    Hashes and returns the message ``message``.

    :param message: bytes
    :rtype: bytes
    """
    digest = ffi.new("unsigned char[]", crypto_hash_sha512_BYTES)
    rc = lib.crypto_hash_sha512(digest, message, len(message))
    ensure(rc == 0, 'Unexpected library error', raising=exc.RuntimeError)
    return ffi.buffer(digest, crypto_hash_sha512_BYTES)[:]
Example #9
0
def crypto_hash_sha512(message):
    """
    Hashes and returns the message ``message``.

    :param message: bytes
    :rtype: bytes
    """
    digest = ffi.new("unsigned char[]", crypto_hash_sha512_BYTES)
    rc = lib.crypto_hash_sha512(digest, message, len(message))
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)
    return ffi.buffer(digest, crypto_hash_sha512_BYTES)[:]
Example #10
0
def crypto_scalarmult_base(n):
    """
    Computes and returns the scalar product of a standard group element and an
    integer ``n``.

    :param n: bytes
    :rtype: bytes
    """
    q = ffi.new("unsigned char[]", crypto_scalarmult_BYTES)

    rc = lib.crypto_scalarmult_base(q, n)
    ensure(rc == 0, 'Unexpected library error', raising=exc.RuntimeError)

    return ffi.buffer(q, crypto_scalarmult_SCALARBYTES)[:]
Example #11
0
def generichash_blake2b_salt_personal(data,
                                      digest_size=crypto_generichash_BYTES,
                                      key=b'',
                                      salt=b'',
                                      person=b''):
    """One shot hash interface
    :param data: the input data to the hash function
    :param digest_size: must be at most
                        :py:data:`.crypto_generichash_BYTES_MAX`;
                        the default digest size is
                        :py:data:`.crypto_generichash_BYTES`
    :type digest_size: int
    :param key: must be at most
                :py:data:`.crypto_generichash_KEYBYTES_MAX` long
    :type key: bytes
    :param salt: must be at most
                 :py:data:`.crypto_generichash_SALTBYTES` long;
                 will be zero-padded if needed
    :type salt: bytes
    :param person: must be at most
                   :py:data:`.crypto_generichash_PERSONALBYTES` long:
                                          will be zero-padded if needed
    :type person: bytes
    :return: digest_size long digest
    :rtype: bytes
    """

    _checkparams(digest_size, key, salt, person)

    ensure(isinstance(data, bytes),
           'Input data must be a bytes sequence',
           raising=exc.TypeError)

    digest = ffi.new("unsigned char[]", digest_size)

    # both _salt and _personal must be zero-padded to the correct length
    _salt = ffi.new("unsigned char []", crypto_generichash_SALTBYTES)
    _person = ffi.new("unsigned char []", crypto_generichash_PERSONALBYTES)

    ffi.memmove(_salt, salt, len(salt))
    ffi.memmove(_person, person, len(person))

    rc = lib.crypto_generichash_blake2b_salt_personal(digest, digest_size,
                                                      data, len(data), key,
                                                      len(key), _salt, _person)
    ensure(rc == 0, 'Unexpected failure', raising=exc.RuntimeError)

    return ffi.buffer(digest, digest_size)[:]
Example #12
0
def crypto_shorthash_siphash24(data, key):
    """Compute a fast, cryptographic quality, keyed hash of the input data

    :param data:
    :type data: bytes
    :param key: len(key) must be equal to
                :py:data:`.KEYBYTES` (16)
    :type key: bytes
    """
    if len(key) != KEYBYTES:
        raise ValueError("Key length must be {0} bytes".format(KEYBYTES))
    digest = ffi.new("unsigned char[]", BYTES)
    rc = lib.crypto_shorthash_siphash24(digest, data, len(data), key)

    utils.ensure(rc == 0, raising=exc.RuntimeError)
    return ffi.buffer(digest, BYTES)[:]
Example #13
0
def generichash_blake2b_update(statebuf, data):
    """Update the blake2b hash state

    :param statebuf: an initialized blake2b state buffer as returned from
                     :py:func:`.crypto_generichash_blake2b_init`
    :type name: bytes
    :param data:
    :type data: bytes
    """

    ensure(isinstance(data, bytes),
           'Input data must be a bytes sequence',
           raising=exc.TypeError)

    rc = lib.crypto_generichash_blake2b_update(statebuf, data, len(data))
    ensure(rc == 0, 'Unexpected failure', raising=exc.RuntimeError)
Example #14
0
def generichash_blake2b_final(statebuf, digest_size):
    """Finalize the blake2b hash state and return the digest.

    :param statebuf:
    :type statebuf: bytes
    :param digest_size:
    :type digest_size: int
    :return: the blake2 digest of the passed-in data stream
    :rtype: bytes
    """

    _digest = ffi.new("unsigned char[]", crypto_generichash_BYTES_MAX)
    rc = lib.crypto_generichash_blake2b_final(statebuf, _digest, digest_size)

    ensure(rc == 0, 'Unexpected failure', raising=exc.RuntimeError)
    return ffi.buffer(_digest, digest_size)[:]
Example #15
0
def crypto_scalarmult_base(n):
    """
    Computes and returns the scalar product of a standard group element and an
    integer ``n``.

    :param n: bytes
    :rtype: bytes
    """
    q = ffi.new("unsigned char[]", crypto_scalarmult_BYTES)

    rc = lib.crypto_scalarmult_base(q, n)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(q, crypto_scalarmult_SCALARBYTES)[:]
Example #16
0
def verify_scryptsalsa208sha256(password_hash, password):
    """
    Takes the output of scryptsalsa208sha256 and compares it against
    a user provided password to see if they are the same

    :param password_hash: bytes
    :param password: bytes
    :rtype: boolean
    """

    ensure(len(password_hash) == SCRYPT_PWHASH_SIZE,
           "The pw_hash must be exactly %s bytes long" %
           nacl.bindings.crypto_pwhash_scryptsalsa208sha256_STRBYTES,
           raising=exc.ValueError)

    return nacl.bindings.crypto_pwhash_scryptsalsa208sha256_str_verify(
        password_hash, password)
Example #17
0
def kdf_scryptsalsa208sha256(size,
                             password,
                             salt,
                             opslimit=SCRYPT_OPSLIMIT_SENSITIVE,
                             memlimit=SCRYPT_MEMLIMIT_SENSITIVE,
                             encoder=nacl.encoding.RawEncoder):
    """
    Makes a key defined from ``password`` and ``salt`` that is
    ``size`` bytes long

    the enclosing module provides the constants

        - :py:const:`.SCRYPT_OPSLIMIT_INTERACTIVE`
        - :py:const:`.SCRYPT_MEMLIMIT_INTERACTIVE`
        - :py:const:`.SCRYPT_OPSLIMIT_SENSITIVE`
        - :py:const:`.SCRYPT_MEMLIMIT_SENSITIVE`

    as a guidance for correct settings respectively for the
    interactive login and the long term key protecting sensitive data
    use cases.

    :param int size: int
    :param bytes password: bytes
    :param bytes salt: bytes
    :param int opslimit:
    :param int memlimit:
    :rtype: bytes
    """
    ensure(len(salt) == SCRYPT_SALTBYTES,
           "The salt must be exactly %s, not %s bytes long" %
           (SCRYPT_SALTBYTES, len(salt)),
           raising=exc.ValueError)

    n_log2, r, p = nacl.bindings.nacl_bindings_pick_scrypt_params(
        opslimit, memlimit)
    maxmem = memlimit + (2**16)

    return encoder.encode(
        nacl.bindings.crypto_pwhash_scryptsalsa208sha256_ll(password,
                                                            salt,
                                                            2**n_log2,
                                                            r,
                                                            p,
                                                            maxmem=maxmem,
                                                            dklen=size))
Example #18
0
def crypto_sign(message, sk):
    """
    Signs the message ``message`` using the secret key ``sk`` and returns the
    signed message.

    :param message: bytes
    :param sk: bytes
    :rtype: bytes
    """
    signed = ffi.new("unsigned char[]", len(message) + crypto_sign_BYTES)
    signed_len = ffi.new("unsigned long long *")

    rc = lib.crypto_sign(signed, signed_len, message, len(message), sk)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(signed, signed_len[0])[:]
Example #19
0
def crypto_box_keypair():
    """
    Returns a randomly generated public and secret key.

    :rtype: (bytes(public_key), bytes(secret_key))
    """
    pk = ffi.new("unsigned char[]", crypto_box_PUBLICKEYBYTES)
    sk = ffi.new("unsigned char[]", crypto_box_SECRETKEYBYTES)

    rc = lib.crypto_box_keypair(pk, sk)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return (
        ffi.buffer(pk, crypto_box_PUBLICKEYBYTES)[:],
        ffi.buffer(sk, crypto_box_SECRETKEYBYTES)[:],
    )
Example #20
0
def crypto_pwhash_scryptsalsa208sha256_str_verify(passwd_hash, passwd):
    """
    Verifies the ``passwd`` against the ``passwd_hash`` that was generated.
    Returns True or False depending on the success

    :param passwd_hash: bytes
    :param passwd: bytes
    :rtype: boolean
    """

    ensure(len(passwd_hash) == SCRYPT_STRBYTES - 1,
           'Invalid password hash',
           raising=exc.ValueError)

    ret = lib.crypto_pwhash_scryptsalsa208sha256_str_verify(
        passwd_hash, passwd, len(passwd))
    ensure(ret == 0, "Wrong password", raising=exc.InvalidkeyError)
    # all went well, therefore:
    return True
Example #21
0
def generichash_blake2b_init(key=b'',
                             salt=b'',
                             person=b'',
                             digest_size=crypto_generichash_BYTES):
    """
    Create a new initialized blake2b hash state

    :param key: must be at most
                :py:data:`.crypto_generichash_KEYBYTES_MAX` long
    :type key: bytes
    :param salt: must be at most
                 :py:data:`.crypto_generichash_SALTBYTES` long;
                 will be zero-padded if needed
    :type salt: bytes
    :param person: must be at most
                   :py:data:`.crypto_generichash_PERSONALBYTES` long:
                   will be zero-padded if needed
    :type person: bytes
    :param digest_size: must be at most
                        :py:data:`.crypto_generichash_BYTES_MAX`;
                        the default digest size is
                        :py:data:`.crypto_generichash_BYTES`
    :type digest_size: int
    :return: an initizialized state buffer
    :rtype: bytes
    """

    _checkparams(digest_size, key, salt, person)

    statebuf = ffi.new("unsigned char[]", crypto_generichash_STATEBYTES)

    # both _salt and _personal must be zero-padded to the correct length
    _salt = ffi.new("unsigned char []", crypto_generichash_SALTBYTES)
    _person = ffi.new("unsigned char []", crypto_generichash_PERSONALBYTES)

    ffi.memmove(_salt, salt, len(salt))
    ffi.memmove(_person, person, len(person))

    rc = lib.crypto_generichash_blake2b_init_salt_personal(
        statebuf, key, len(key), digest_size, _salt, _person)
    ensure(rc == 0, 'Unexpected failure', raising=exc.RuntimeError)

    return statebuf
Example #22
0
File: utils.py Project: ofek/pynacl
def sodium_memcmp(inp1, inp2):
    """
    Compare contents of two memory regions in constant time
    """
    ensure(isinstance(inp1, bytes), raising=exc.TypeError)
    ensure(isinstance(inp2, bytes), raising=exc.TypeError)

    ln = max(len(inp1), len(inp2))

    buf1 = ffi.new("char []", ln)
    buf2 = ffi.new("char []", ln)

    ffi.memmove(buf1, inp1, len(inp1))
    ffi.memmove(buf2, inp2, len(inp2))

    eqL = len(inp1) == len(inp2)
    eqC = lib.sodium_memcmp(buf1, buf2, ln) == 0

    return eqL and eqC
Example #23
0
def sodium_memcmp(inp1, inp2):
    """
    Compare contents of two memory regions in constant time
    """
    ensure(isinstance(inp1, bytes),
           raising=exc.TypeError)
    ensure(isinstance(inp2, bytes),
           raising=exc.TypeError)

    ln = max(len(inp1), len(inp2))

    buf1 = ffi.new("char []", ln)
    buf2 = ffi.new("char []", ln)

    ffi.memmove(buf1, inp1, len(inp1))
    ffi.memmove(buf2, inp2, len(inp2))

    eqL = len(inp1) == len(inp2)
    eqC = lib.sodium_memcmp(buf1, buf2, ln) == 0

    return eqL and eqC
Example #24
0
def crypto_sign_seed_keypair(seed):
    """
    Computes and returns the public key and secret key using the seed ``seed``.

    :param seed: bytes
    :rtype: (bytes(public_key), bytes(secret_key))
    """
    if len(seed) != crypto_sign_SEEDBYTES:
        raise ValueError("Invalid seed")

    pk = ffi.new("unsigned char[]", crypto_sign_PUBLICKEYBYTES)
    sk = ffi.new("unsigned char[]", crypto_sign_SECRETKEYBYTES)

    rc = lib.crypto_sign_seed_keypair(pk, sk, seed)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return (
        ffi.buffer(pk, crypto_sign_PUBLICKEYBYTES)[:],
        ffi.buffer(sk, crypto_sign_SECRETKEYBYTES)[:],
    )
Example #25
0
def crypto_secretbox(message, nonce, key):
    """
    Encrypts and returns the message ``message`` with the secret ``key`` and
    the nonce ``nonce``.

    :param message: bytes
    :param nonce: bytes
    :param key: bytes
    :rtype: bytes
    """
    if len(key) != crypto_secretbox_KEYBYTES:
        raise ValueError("Invalid key")

    if len(nonce) != crypto_secretbox_NONCEBYTES:
        raise ValueError("Invalid nonce")

    padded = b"\x00" * crypto_secretbox_ZEROBYTES + message
    ciphertext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_secretbox(ciphertext, padded, len(padded), nonce, key)
    ensure(res == 0, "Encryption failed", raising=exc.CryptoError)

    ciphertext = ffi.buffer(ciphertext, len(padded))
    return ciphertext[crypto_secretbox_BOXZEROBYTES:]
Example #26
0
def crypto_secretbox(message, nonce, key):
    """
    Encrypts and returns the message ``message`` with the secret ``key`` and
    the nonce ``nonce``.

    :param message: bytes
    :param nonce: bytes
    :param key: bytes
    :rtype: bytes
    """
    if len(key) != crypto_secretbox_KEYBYTES:
        raise ValueError("Invalid key")

    if len(nonce) != crypto_secretbox_NONCEBYTES:
        raise ValueError("Invalid nonce")

    padded = b"\x00" * crypto_secretbox_ZEROBYTES + message
    ciphertext = ffi.new("unsigned char[]", len(padded))

    res = lib.crypto_secretbox(ciphertext, padded, len(padded), nonce, key)
    ensure(res == 0, "Encryption failed", raising=exc.CryptoError)

    ciphertext = ffi.buffer(ciphertext, len(padded))
    return ciphertext[crypto_secretbox_BOXZEROBYTES:]
Example #27
0
def crypto_sign_ed25519_sk_to_curve25519(secret_key_bytes):
    """
    Converts a secret Ed25519 key (encoded as bytes ``secret_key_bytes``) to
    a secret Curve25519 key as bytes.

    Raises a ValueError if ``secret_key_bytes``is not of length
    ``crypto_sign_SECRETKEYBYTES``

    :param public_key_bytes: bytes
    :rtype: bytes
    """
    if len(secret_key_bytes) != crypto_sign_SECRETKEYBYTES:
        raise ValueError("Invalid curve public key")

    curve_secret_key_len = crypto_sign_curve25519_BYTES
    curve_secret_key = ffi.new("unsigned char[]", curve_secret_key_len)

    rc = lib.crypto_sign_ed25519_sk_to_curve25519(curve_secret_key,
                                                  secret_key_bytes)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(curve_secret_key, curve_secret_key_len)[:]
Example #28
0
def crypto_box_beforenm(pk, sk):
    """
    Computes and returns the shared key for the public key ``pk`` and the
    secret key ``sk``. This can be used to speed up operations where the same
    set of keys is going to be used multiple times.

    :param pk: bytes
    :param sk: bytes
    :rtype: bytes
    """
    if len(pk) != crypto_box_PUBLICKEYBYTES:
        raise ValueError("Invalid public key")

    if len(sk) != crypto_box_SECRETKEYBYTES:
        raise ValueError("Invalid secret key")

    k = ffi.new("unsigned char[]", crypto_box_BEFORENMBYTES)

    rc = lib.crypto_box_beforenm(k, pk, sk)
    ensure(rc == 0,
           'Unexpected library error',
           raising=exc.RuntimeError)

    return ffi.buffer(k, crypto_box_BEFORENMBYTES)[:]
Example #29
0
def _sodium_init():
    ensure(lib.sodium_init() != -1,
           "Could not initialize sodium",
           raising=exc.RuntimeError)
Example #30
0
def _sodium_init():
    ensure(lib.sodium_init() != -1, "Could not initialize sodium", raising=exc.RuntimeError)
Example #31
0
def _check_memory_occupation(n, r, p, maxmem=SCRYPT_MAX_MEM):
    ensure(r != 0, 'Invalid block size', raising=exc.ValueError)

    ensure(p != 0, 'Invalid parallelization factor', raising=exc.ValueError)

    ensure((n & (n - 1)) == 0,
           'Cost factor must be a power of 2',
           raising=exc.ValueError)

    ensure(n > 1, 'Cost factor must be at least 2', raising=exc.ValueError)

    ensure(p <= SCRYPT_PR_MAX / r,
           'p*r is greater than {0}'.format(SCRYPT_PR_MAX),
           raising=exc.ValueError)

    ensure(n < (1 << (16 * r)), raising=exc.ValueError)

    Blen = p * 128 * r

    i = UINT64_MAX / 128

    ensure(n + 2 <= i / r, raising=exc.ValueError)

    Vlen = 32 * r * (n + 2) * 4

    ensure(Blen <= UINT64_MAX - Vlen, raising=exc.ValueError)

    ensure(Blen <= sys.maxsize - Vlen, raising=exc.ValueError)

    ensure(Blen + Vlen <= maxmem,
           'Memory limit would be exceeded with the choosen n, r, p',
           raising=exc.ValueError)
Example #32
0
def crypto_pwhash_scryptsalsa208sha256_ll(passwd,
                                          salt,
                                          n,
                                          r,
                                          p,
                                          dklen=64,
                                          maxmem=SCRYPT_MAX_MEM):
    """
    Derive a cryptographic key using the ``passwd`` and ``salt``
    given as input.

    The work factor can be tuned by by picking different
    values for the parameters

    :param bytes passwd:
    :param bytes salt:
    :param bytes salt: *must* be *exactly* :py:const:`.SALTBYTES` long
    :param int dklen:
    :param int opslimit:
    :param int n:
    :param int r: block size,
    :param int p: the parallelism factor
    :param int maxmem: the maximum available memory available for scrypt's
                       operations
    :rtype: bytes
    """
    ensure(isinstance(n, int), raising=TypeError)
    ensure(isinstance(r, int), raising=TypeError)
    ensure(isinstance(p, int), raising=TypeError)

    ensure(isinstance(passwd, bytes), raising=TypeError)
    ensure(isinstance(salt, bytes), raising=TypeError)

    _check_memory_occupation(n, r, p, maxmem)

    buf = ffi.new("uint8_t[]", dklen)

    ret = lib.crypto_pwhash_scryptsalsa208sha256_ll(passwd, len(passwd), salt,
                                                    len(salt), n, r, p, buf,
                                                    dklen)

    ensure(ret == 0,
           'Unexpected failure in key derivation',
           raising=exc.RuntimeError)

    return ffi.buffer(ffi.cast("char *", buf), dklen)[:]
Example #33
0
def _checkparams(digest_size, key, salt, person):
    """Check hash paramters"""
    ensure(isinstance(key, bytes),
           'Key must be a bytes sequence',
           raising=exc.TypeError)

    ensure(isinstance(salt, bytes),
           'Salt must be a bytes sequence',
           raising=exc.TypeError)

    ensure(isinstance(person, bytes),
           'Person must be a bytes sequence',
           raising=exc.TypeError)

    ensure(isinstance(digest_size, integer_types),
           'Digest size must be an integer number',
           raising=exc.TypeError)

    ensure(digest_size <= crypto_generichash_BYTES_MAX,
           _TOOBIG.format("Digest_size", crypto_generichash_BYTES_MAX),
           raising=exc.ValueError)

    ensure(len(key) <= crypto_generichash_KEYBYTES_MAX,
           _OVERLONG.format("Key", crypto_generichash_KEYBYTES_MAX),
           raising=exc.ValueError)

    ensure(len(salt) <= crypto_generichash_SALTBYTES,
           _OVERLONG.format("Salt", crypto_generichash_SALTBYTES),
           raising=exc.ValueError)

    ensure(len(person) <= crypto_generichash_PERSONALBYTES,
           _OVERLONG.format("Person", crypto_generichash_PERSONALBYTES),
           raising=exc.ValueError)