Пример #1
0
def generichash_blake2b_state_copy(statebuf):
    """Return a copy of the given blake2b hash state"""

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

    return newstate
Пример #2
0
def sodium_pad(s, blocksize):
    """
    Pad the input bytearray ``s`` to a multiple of ``blocksize``
    using the ISO/IEC 7816-4 algorithm

    :param s: input bytes string
    :type s: bytes
    :param blocksize:
    :type blocksize: int
    :return: padded string
    :rtype: bytes
    """
    ensure(isinstance(s, bytes),
           raising=exc.TypeError)
    ensure(isinstance(blocksize, integer_types),
           raising=exc.TypeError)
    if blocksize <= 0:
        raise exc.ValueError
    s_len = len(s)
    m_len = s_len + blocksize
    buf = ffi.new("unsigned char []", m_len)
    p_len = ffi.new("size_t []", 1)
    ffi.memmove(buf, s, s_len)
    rc = lib.sodium_pad(p_len, buf, s_len, blocksize, m_len)
    ensure(rc == 0, "Padding failure", raising=exc.CryptoError)
    return ffi.buffer(buf, p_len[0])[:]
Пример #3
0
def sodium_add(a, b):
    """
    Given a couple of *same-sized* byte sequences, interpreted as the
    little-endian representation of two unsigned integers, compute
    the modular addition of the represented values, in constant time for
    a given common length of the byte sequences.

    :param a: input bytes buffer
    :type a: bytes
    :param b: input bytes buffer
    :type b: bytes
    :return: a byte-sequence representing, as a little-endian big integer,
             the integer value of ``(to_int(a) + to_int(b)) mod 2^(8*len(a))``
    :rtype: bytes
    """
    ensure(isinstance(a, bytes),
           raising=exc.TypeError)
    ensure(isinstance(b, bytes),
           raising=exc.TypeError)
    ln = len(a)
    ensure(len(b) == ln,
           raising=exc.TypeError)

    buf_a = ffi.new("unsigned char []", ln)
    buf_b = ffi.new("unsigned char []", ln)

    ffi.memmove(buf_a, a, ln)
    ffi.memmove(buf_b, b, ln)

    lib.sodium_add(buf_a, buf_b, ln)

    return ffi.buffer(buf_a, ln)[:]
Пример #4
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)[:]
Пример #5
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
Пример #6
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
Пример #7
0
def sodium_increment(inp):
    """
    Increment the value of a byte-sequence interpreted
    as the little-endian representation of a unsigned big integer.

    :param inp: input bytes buffer
    :type inp: bytes
    :return: a byte-sequence representing, as a little-endian
             unsigned big integer, the value ``to_int(inp)``
             incremented by one.
    :rtype: bytes

    """
    ensure(isinstance(inp, bytes), raising=exc.TypeError)

    ln = len(inp)
    buf = ffi.new("unsigned char []", ln)

    ffi.memmove(buf, inp, ln)

    lib.sodium_increment(buf, ln)

    return ffi.buffer(buf, ln)[:]
Пример #8
0
def sodium_pad(s, blocksize):
    """
    Pad the input bytearray ``s`` to a multiple of ``blocksize``
    using the ISO/IEC 7816-4 algorithm

    :param s: input bytes string
    :type s: bytes
    :param blocksize:
    :type blocksize: int
    :return: padded string
    :rtype: bytes
    """
    ensure(isinstance(s, bytes), raising=exc.TypeError)
    ensure(isinstance(blocksize, integer_types), raising=exc.TypeError)
    if blocksize <= 0:
        raise exc.ValueError
    s_len = len(s)
    m_len = s_len + blocksize
    buf = ffi.new("unsigned char []", m_len)
    p_len = ffi.new("size_t []", 1)
    ffi.memmove(buf, s, s_len)
    rc = lib.sodium_pad(p_len, buf, s_len, blocksize, m_len)
    ensure(rc == 0, "Padding failure", raising=exc.CryptoError)
    return ffi.buffer(buf, p_len[0])[:]
Пример #9
0
def sodium_increment(inp):
    """
    Increment the value of a byte-sequence interpreted
    as the little-endian representation of a unsigned big integer.

    :param inp: input bytes buffer
    :type inp: bytes
    :return: a byte-sequence representing, as a little-endian
             unsigned big integer, the value ``to_int(inp)``
             incremented by one.
    :rtype: bytes

    """
    ensure(isinstance(inp, bytes),
           raising=exc.TypeError)

    ln = len(inp)
    buf = ffi.new("unsigned char []", ln)

    ffi.memmove(buf, inp, ln)

    lib.sodium_increment(buf, ln)

    return ffi.buffer(buf, ln)[:]
Пример #10
0
 def copy(self):
     _st = self.__class__(self.digest_size)
     ffi.memmove(_st._statebuf, self._statebuf,
                 crypto_generichash_STATEBYTES)
     return _st
Пример #11
0
 def copy(self):
     _st = self.__class__(self.digest_size)
     ffi.memmove(_st._statebuf,
                 self._statebuf, crypto_generichash_STATEBYTES)
     return _st
Пример #12
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
    """
    ensure(isinstance(data, bytes),
           'Input data must be a bytes sequence',
           raising=exc.TypeError)

    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)

    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)[:]