Ejemplo n.º 1
0
def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen):
    emLen = ceil_div(emBits, 8)
    lmask = 0
    for i in xrange(8 * emLen - emBits):
        lmask = lmask >> 1 | 128

    if emLen < mhash.digest_size + sLen + 2:
        return False
    if ord(em[-1:]) != 188:
        return False
    maskedDB = em[:emLen - mhash.digest_size - 1]
    h = em[emLen - mhash.digest_size - 1:-1]
    if lmask & bord(em[0]):
        return False
    dbMask = mgf(h, emLen - mhash.digest_size - 1)
    db = strxor(maskedDB, dbMask)
    db = bchr(bord(db[0]) & ~lmask) + db[1:]
    if not db.startswith(bchr(0) * (emLen - mhash.digest_size - sLen - 2) + bchr(1)):
        return False
    salt = b('')
    if sLen:
        salt = db[-sLen:]
    try:
        hp = mhash.new(bchr(0) * 8 + mhash.digest() + salt).digest()
    except AttributeError:
        hp = Hash_new(mhash, bchr(0) * 8 + mhash.digest() + salt).digest()

    return False if h != hp else True
Ejemplo n.º 2
0
def MGF1(mgfSeed, maskLen, hash):
    T = b('')
    for counter in xrange(ceil_div(maskLen, hash.digest_size)):
        c = long_to_bytes(counter, 4)
        try:
            T = T + hash.new(mgfSeed + c).digest()
        except AttributeError:
            T = T + Hash_new(hash, mgfSeed + c).digest()

    return T[:maskLen]
Ejemplo n.º 3
0
def MGF1(mgfSeed, maskLen, hash):
    """Mask Generation Function, described in B.2.1"""
    T = b("")
    for counter in range(ceil_div(maskLen, hash.digest_size)):
        c = long_to_bytes(counter, 4)
        try:
            T = T + hash.new(mgfSeed + c).digest()
        except AttributeError:
            # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
            T = T + Hash_new(hash, mgfSeed + c).digest()
    assert (len(T) >= maskLen)
    return T[:maskLen]
Ejemplo n.º 4
0
def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen):
    emLen = ceil_div(emBits, 8)
    lmask = 0
    for i in xrange(8 * emLen - emBits):
        lmask = lmask >> 1 | 128

    if emLen < mhash.digest_size + sLen + 2:
        raise ValueError('Digest or salt length are too long for given key size.')
    salt = b('')
    if randFunc and sLen > 0:
        salt = randFunc(sLen)
    try:
        h = mhash.new(bchr(0) * 8 + mhash.digest() + salt)
    except AttributeError:
        h = Hash_new(mhash, bchr(0) * 8 + mhash.digest() + salt)

    db = bchr(0) * (emLen - sLen - mhash.digest_size - 2) + bchr(1) + salt
    dbMask = mgf(h.digest(), emLen - mhash.digest_size - 1)
    maskedDB = strxor(db, dbMask)
    maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:]
    em = maskedDB + h.digest() + bchr(188)
    return em
Ejemplo n.º 5
0
def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen):
    """
    Implement the ``EMSA-PSS-VERIFY`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.2).

    ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     mhash : hash object
            The hash object that holds the digest of the message to be verified.
     em : string
            The signature to verify, therefore proving that the sender really signed
            the message that was received.
     emBits : int
            Length of the final encoding (em), in bits.
     mgf : callable
            A mask generation function that accepts two parameters: a string to
            use as seed, and the lenth of the mask to generate, in bytes.
     sLen : int
            Length of the salt, in bytes.

    :Return: 0 if the encoding is consistent, 1 if it is inconsistent.

    :Raise ValueError:
        When digest or salt length are too big.
    """

    emLen = ceil_div(emBits, 8)

    # Bitmask of digits that fill up
    lmask = 0
    for i in range(8 * emLen - emBits):
        lmask = lmask >> 1 | 0x80

    # Step 1 and 2 have been already done
    # Step 3
    if emLen < mhash.digest_size + sLen + 2:
        return False
    # Step 4
    if ord(em[-1:]) != 0xBC:
        return False
    # Step 5
    maskedDB = em[:emLen - mhash.digest_size - 1]
    h = em[emLen - mhash.digest_size - 1:-1]
    # Step 6
    if lmask & bord(em[0]):
        return False
    # Step 7
    dbMask = mgf(h, emLen - mhash.digest_size - 1)
    # Step 8
    db = strxor(maskedDB, dbMask)
    # Step 9
    db = bchr(bord(db[0]) & ~lmask) + db[1:]
    # Step 10
    if not db.startswith(
            bchr(0x00) * (emLen - mhash.digest_size - sLen - 2) + bchr(0x01)):
        return False
    # Step 11
    salt = b("")
    if sLen: salt = db[-sLen:]
    # Step 12 and 13
    try:
        hp = mhash.new(bchr(0x00) * 8 + mhash.digest() + salt).digest()
    except AttributeError:
        # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
        hp = Hash_new(mhash, bchr(0x00) * 8 + mhash.digest() + salt).digest()
    # Step 14
    if h != hp:
        return False
    return True
Ejemplo n.º 6
0
def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen):
    """
    Implement the ``EMSA-PSS-ENCODE`` function, as defined
    in PKCS#1 v2.1 (RFC3447, 9.1.1).

    The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M`` as input,
    and hash it internally. Here, we expect that the message has already
    been hashed instead.

    :Parameters:
     mhash : hash object
            The hash object that holds the digest of the message being signed.
     emBits : int
            Maximum length of the final encoding, in bits.
     randFunc : callable
            An RNG function that accepts as only parameter an int, and returns
            a string of random bytes, to be used as salt.
     mgf : callable
            A mask generation function that accepts two parameters: a string to
            use as seed, and the lenth of the mask to generate, in bytes.
     sLen : int
            Length of the salt, in bytes.

    :Return: An ``emLen`` byte long string that encodes the hash
            (with ``emLen = \ceil(emBits/8)``).

    :Raise ValueError:
        When digest or salt length are too big.
    """

    emLen = ceil_div(emBits, 8)

    # Bitmask of digits that fill up
    lmask = 0
    for i in range(8 * emLen - emBits):
        lmask = lmask >> 1 | 0x80

    # Step 1 and 2 have been already done
    # Step 3
    if emLen < mhash.digest_size + sLen + 2:
        raise ValueError(
            "Digest or salt length are too long for given key size.")
    # Step 4
    salt = b("")
    if randFunc and sLen > 0:
        salt = randFunc(sLen)
    # Step 5 and 6
    try:
        h = mhash.new(bchr(0x00) * 8 + mhash.digest() + salt)
    except AttributeError:
        # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
        h = Hash_new(mhash, bchr(0x00) * 8 + mhash.digest() + salt)
    # Step 7 and 8
    db = bchr(0x00) * (emLen - sLen - mhash.digest_size -
                       2) + bchr(0x01) + salt
    # Step 9
    dbMask = mgf(h.digest(), emLen - mhash.digest_size - 1)
    # Step 10
    maskedDB = strxor(db, dbMask)
    # Step 11
    maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:]
    # Step 12
    em = maskedDB + h.digest() + bchr(0xBC)
    return em