Exemplo n.º 1
0
def teredoAddrExtractInfo(x):
    """
    Extract information from a Teredo address. Return value is
    a 4-tuple made of IPv4 address of Teredo server, flag value (int),
    mapped address (non obfuscated) and mapped port (non obfuscated).
    No specific checks are performed on passed address.
    """
    addr = inet_pton(socket.AF_INET6, x)
    server = inet_ntop(socket.AF_INET, addr[4:8])
    flag = struct.unpack("!H", addr[8:10])[0]
    mappedport = struct.unpack("!H", strxor(addr[10:12], b'\xff' * 2))[0]
    mappedaddr = inet_ntop(socket.AF_INET, strxor(addr[12:16], b'\xff' * 4))
    return server, flag, mappedaddr, mappedport
Exemplo n.º 2
0
def teredoAddrExtractInfo(x):
    """
    Extract information from a Teredo address. Return value is
    a 4-tuple made of IPv4 address of Teredo server, flag value (int),
    mapped address (non obfuscated) and mapped port (non obfuscated).
    No specific checks are performed on passed address.
    """
    addr = inet_pton(socket.AF_INET6, x)
    server = inet_ntop(socket.AF_INET, addr[4:8])
    flag = struct.unpack("!H", addr[8:10])[0]
    mappedport = struct.unpack("!H", strxor(addr[10:12], b'\xff' * 2))[0]
    mappedaddr = inet_ntop(socket.AF_INET, strxor(addr[12:16], b'\xff' * 4))
    return server, flag, mappedaddr, mappedport
Exemplo n.º 3
0
Arquivo: prf.py Projeto: Epiann1/shiva
def _tls_PRF(secret, label, seed, req_len):
    """
    Provides the implementation of TLS PRF function as defined in
    section 5 of RFC 4346:

    PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
                               P_SHA-1(S2, label + seed)

    Parameters are:

    - secret: the secret used by the HMAC in the 2 expansion
              functions (S1 and S2 are the halves of this secret).
    - label: specific label as defined in various sections of the RFC
             depending on the use of the generated PRF keystream
    - seed: the seed used by the expansion functions.
    - req_len: amount of keystream to be generated
    """
    l = (len(secret) + 1) / 2
    S1 = secret[:l]
    S2 = secret[-l:]

    a1 = _tls_P_MD5(S1, label + seed, req_len)
    a2 = _tls_P_SHA1(S2, label + seed, req_len)

    return strxor(a1, a2)
Exemplo n.º 4
0
Arquivo: prf.py Projeto: commial/scapy
def _tls_PRF(secret, label, seed, req_len):
    """
    Provides the implementation of TLS PRF function as defined in
    section 5 of RFC 4346:

    PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
                               P_SHA-1(S2, label + seed)

    Parameters are:

    - secret: the secret used by the HMAC in the 2 expansion
              functions (S1 and S2 are the halves of this secret).
    - label: specific label as defined in various sections of the RFC
             depending on the use of the generated PRF keystream
    - seed: the seed used by the expansion functions.
    - req_len: amount of keystream to be generated
    """
    tmp_len = (len(secret) + 1) // 2
    S1 = secret[:tmp_len]
    S2 = secret[-tmp_len:]

    a1 = _tls_P_MD5(S1, label + seed, req_len)
    a2 = _tls_P_SHA1(S2, label + seed, req_len)

    return strxor(a1, a2)
Exemplo n.º 5
0
def pkcs_emsa_pss_verify(M, EM, emBits, h, mgf, sLen):
    """
    Implements EMSA-PSS-VERIFY() function described in Sect. 9.1.2 of RFC 3447

    Input:
       M     : message to be encoded, an octet string
       EM    : encoded message, an octet string of length emLen=ceil(emBits/8)
       emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM)
       h     : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
               'sha256', 'sha384'). hLen denotes the length in octets of
               the hash function output.
       mgf   : the mask generation function f : seed, maskLen -> mask
       sLen  : intended length in octets of the salt

    Output:
       True if the verification is ok, False otherwise.
    """

    # 1) is not done
    hLen = _hashFuncParams[h][0]  # 2)
    hFunc = _hashFuncParams[h][2]
    mHash = hFunc(M)
    emLen = int(math.ceil(emBits / 8.))  # 3)
    if emLen < hLen + sLen + 2:
        return False
    if EM[-1] != '\xbc':  # 4)
        return False
    l = emLen - hLen - 1  # 5)
    maskedDB = EM[:l]
    H = EM[l:l + hLen]
    l = (8 * emLen - emBits) / 8  # 6)
    rem = 8 * emLen - emBits - 8 * l  # additionnal bits
    andMask = l * '\xff'
    if rem:
        val = reduce(lambda x, y: x + y, map(lambda x: 1 << x, range(8 - rem)))
        j = chr(~val & 0xff)
        andMask += j
        l += 1
    if strand(maskedDB[:l], andMask) != '\x00' * l:
        return False
    dbMask = mgf(H, emLen - hLen - 1)  # 7)
    DB = strxor(maskedDB, dbMask)  # 8)
    l = (8 * emLen - emBits) / 8  # 9)
    rem = 8 * emLen - emBits - 8 * l  # additionnal bits
    andMask = l * '\x00'
    if rem:
        j = chr(
            reduce(lambda x, y: x + y, map(lambda x: 1 << x, range(8 - rem))))
        andMask += j
        l += 1
    DB = strand(DB[:l], andMask) + DB[l:]
    l = emLen - hLen - sLen - 1  # 10)
    if DB[:l] != '\x00' * (l - 1) + '\x01':
        return False
    salt = DB[-sLen:]  # 11)
    MPrime = '\x00' * 8 + mHash + salt  # 12)
    HPrime = hFunc(MPrime)  # 13)
    return H == HPrime  # 14)
Exemplo n.º 6
0
def pkcs_emsa_pss_verify(M, EM, emBits, h, mgf, sLen):
    """
    Implements EMSA-PSS-VERIFY() function described in Sect. 9.1.2 of RFC 3447

    Input:
       M     : message to be encoded, an octet string
       EM    : encoded message, an octet string of length emLen = ceil(emBits/8)
       emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM)
       h     : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
               'sha256', 'sha384'). hLen denotes the length in octets of
               the hash function output.
       mgf   : the mask generation function f : seed, maskLen -> mask
       sLen  : intended length in octets of the salt

    Output:
       True if the verification is ok, False otherwise.
    """

    # 1) is not done
    hLen = _hashFuncParams[h][0]                             # 2)
    hFunc = _hashFuncParams[h][1]
    mHash = hFunc(M)
    emLen = int(math.ceil(emBits/8.))                        # 3)
    if emLen < hLen + sLen + 2:
        return False
    if EM[-1] != '\xbc':                                     # 4)
        return False
    l = emLen - hLen - 1                                     # 5)
    maskedDB = EM[:l]
    H = EM[l:l+hLen]
    l = (8*emLen - emBits)/8                                 # 6)
    rem = 8*emLen - emBits - 8*l # additionnal bits
    andMask = l*'\xff'
    if rem:
        val = reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem)))
        j = chr(~val & 0xff)
        andMask += j
        l += 1
    if strand(maskedDB[:l], andMask) != '\x00'*l:
        return False
    dbMask = mgf(H, emLen - hLen - 1)                        # 7)
    DB = strxor(maskedDB, dbMask)                            # 8)
    l = (8*emLen - emBits)/8                                 # 9)
    rem = 8*emLen - emBits - 8*l # additionnal bits
    andMask = l*'\x00'
    if rem:
        j = chr(reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem))))
        andMask += j
        l += 1
    DB = strand(DB[:l], andMask) + DB[l:]
    l = emLen - hLen - sLen - 1                              # 10)
    if DB[:l] != '\x00'*(l-1) + '\x01':
        return False
    salt = DB[-sLen:]                                        # 11)
    MPrime = '\x00'*8 + mHash + salt                         # 12)
    HPrime = hFunc(MPrime)                                   # 13)
    return H == HPrime                                       # 14)
Exemplo n.º 7
0
 def hash(self):
     s1 = struct.pack("!H", self.sport)
     s2 = struct.pack("!H", self.dport)
     family = socket.AF_INET
     if ':' in self.ipsrc:
         family = socket.AF_INET6
     s1 += socket.inet_pton(family, self.ipsrc)
     s2 += socket.inet_pton(family, self.ipdst)
     return strxor(s1, s2)
Exemplo n.º 8
0
 def hash(self):
     s1 = struct.pack("!H", self.sport)
     s2 = struct.pack("!H", self.dport)
     family = socket.AF_INET
     if ':' in self.ipsrc:
         family = socket.AF_INET6
     s1 += socket.inet_pton(family, self.ipsrc)
     s2 += socket.inet_pton(family, self.ipdst)
     return strxor(s1, s2)
Exemplo n.º 9
0
 def hashret(self):
     if (self.proto == socket.IPPROTO_ICMP) and (isinstance(
             self.payload, ICMP)) and (self.payload.type
                                       in [3, 4, 5, 11, 12]):
         return self.payload.payload.hashret()
     if not conf.checkIPinIP and self.proto in [4, 41]:  # IP, IPv6
         return self.payload.hashret()
     if self.dst == "224.0.0.251":  # mDNS
         return struct.pack("B", self.proto) + self.payload.hashret()
     if conf.checkIPsrc and conf.checkIPaddr:
         return strxor(socket.inet_pton(socket.AF_INET, self.src),
                       socket.inet_pton(
                           socket.AF_INET, self.dst)) + struct.pack(
                               "B", self.proto) + self.payload.hashret()
     return struct.pack("B", self.proto) + self.payload.hashret()
Exemplo n.º 10
0
def pkcs_emsa_pss_encode(M, emBits, h, mgf, sLen):
    """
    Implements EMSA-PSS-ENCODE() function described in Sect. 9.1.1 of RFC 3447

    Input:
       M     : message to be encoded, an octet string
       emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM),
               where EM is the encoded message, output of the function.
       h     : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
               'sha256', 'sha384'). hLen denotes the length in octets of
               the hash function output.
       mgf   : the mask generation function f : seed, maskLen -> mask
       sLen  : intended length in octets of the salt

    Output:
       encoded message, an octet string of length emLen = ceil(emBits/8)

    On error, None is returned.
    """

    # 1) is not done
    hLen = _hashFuncParams[h][0]  # 2)
    hFunc = _hashFuncParams[h][2]
    mHash = hFunc(M)
    emLen = int(math.ceil(emBits / 8.))
    if emLen < hLen + sLen + 2:  # 3)
        warning("encoding error (emLen < hLen + sLen + 2)")
        return None
    salt = randstring(sLen)  # 4)
    MPrime = '\x00' * 8 + mHash + salt  # 5)
    H = hFunc(MPrime)  # 6)
    PS = '\x00' * (emLen - sLen - hLen - 2)  # 7)
    DB = PS + '\x01' + salt  # 8)
    dbMask = mgf(H, emLen - hLen - 1)  # 9)
    maskedDB = strxor(DB, dbMask)  # 10)
    l = (8 * emLen - emBits) / 8  # 11)
    rem = 8 * emLen - emBits - 8 * l  # additionnal bits
    andMask = l * '\x00'
    if rem:
        j = chr(
            reduce(lambda x, y: x + y, map(lambda x: 1 << x, range(8 - rem))))
        andMask += j
        l += 1
    maskedDB = strand(maskedDB[:l], andMask) + maskedDB[l:]
    EM = maskedDB + H + '\xbc'  # 12)
    return EM  # 13)
Exemplo n.º 11
0
def pkcs_emsa_pss_encode(M, emBits, h, mgf, sLen):
    """
    Implements EMSA-PSS-ENCODE() function described in Sect. 9.1.1 of RFC 3447

    Input:
       M     : message to be encoded, an octet string
       emBits: maximal bit length of the integer resulting of pkcs_os2ip(EM),
               where EM is the encoded message, output of the function.
       h     : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
               'sha256', 'sha384'). hLen denotes the length in octets of
               the hash function output.
       mgf   : the mask generation function f : seed, maskLen -> mask
       sLen  : intended length in octets of the salt

    Output:
       encoded message, an octet string of length emLen = ceil(emBits/8)

    On error, None is returned.
    """

    # 1) is not done
    hLen = _hashFuncParams[h][0]                             # 2)
    hFunc = _hashFuncParams[h][1]
    mHash = hFunc(M)
    emLen = int(math.ceil(emBits/8.))
    if emLen < hLen + sLen + 2:                              # 3)
        warning("encoding error (emLen < hLen + sLen + 2)")
        return None
    salt = randstring(sLen)                                  # 4)
    MPrime = '\x00'*8 + mHash + salt                         # 5)
    H = hFunc(MPrime)                                        # 6)
    PS = '\x00'*(emLen - sLen - hLen - 2)                    # 7)
    DB = PS + '\x01' + salt                                  # 8)
    dbMask = mgf(H, emLen - hLen - 1)                        # 9)
    maskedDB = strxor(DB, dbMask)                            # 10)
    l = (8*emLen - emBits)/8                                 # 11)
    rem = 8*emLen - emBits - 8*l # additionnal bits
    andMask = l*'\x00'
    if rem:
        j = chr(reduce(lambda x,y: x+y, map(lambda x: 1<<x, range(8-rem))))
        andMask += j
        l += 1
    maskedDB = strand(maskedDB[:l], andMask) + maskedDB[l:]
    EM = maskedDB + H + '\xbc'                               # 12)
    return EM                                                # 13)
Exemplo n.º 12
0
    def _rsaes_oaep_encrypt(self, M, h=None, mgf=None, L=None):
        """
        Internal method providing RSAES-OAEP-ENCRYPT as defined in Sect.
        7.1.1 of RFC 3447. Not intended to be used directly. Please, see
        encrypt() method for type "OAEP".


        Input:
           M  : message to be encrypted, an octet string of length mLen
                where mLen <= k - 2*hLen - 2 (k denotes the length in octets
                of the RSA modulus and hLen the length in octets of the hash
                function output)
           h  : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
                'sha256', 'sha384'). hLen denotes the length in octets of
                the hash function output. 'sha1' is used by default if not
                provided.
           mgf: the mask generation function f : seed, maskLen -> mask
           L  : optional label to be associated with the message; the default
                value for L, if not provided is the empty string

        Output:
           ciphertext, an octet string of length k

        On error, None is returned.
        """
        # The steps below are the one described in Sect. 7.1.1 of RFC 3447.
        # 1) Length Checking
        # 1.a) is not done
        mLen = len(M)
        if h is None:
            h = "sha1"
        if not _hashFuncParams.has_key(h):
            warning("Key._rsaes_oaep_encrypt(): unknown hash function %s.", h)
            return None
        hLen = _hashFuncParams[h][0]
        hFun = _hashFuncParams[h][1]
        k = self.modulusLen / 8
        if mLen > k - 2 * hLen - 2:  # 1.b)
            warning("Key._rsaes_oaep_encrypt(): message too long.")
            return None

        # 2) EME-OAEP encoding
        if L is None:  # 2.a)
            L = ""
        lHash = hFun(L)
        PS = '\x00' * (k - mLen - 2 * hLen - 2)  # 2.b)
        DB = lHash + PS + '\x01' + M  # 2.c)
        seed = randstring(hLen)  # 2.d)
        if mgf is None:  # 2.e)
            mgf = lambda x, y: pkcs_mgf1(x, y, h)
        dbMask = mgf(seed, k - hLen - 1)
        maskedDB = strxor(DB, dbMask)  # 2.f)
        seedMask = mgf(maskedDB, hLen)  # 2.g)
        maskedSeed = strxor(seed, seedMask)  # 2.h)
        EM = '\x00' + maskedSeed + maskedDB  # 2.i)

        # 3) RSA Encryption
        m = pkcs_os2ip(EM)  # 3.a)
        c = self._rsaep(m)  # 3.b)
        C = pkcs_i2osp(c, k)  # 3.c)

        return C  # 4)
Exemplo n.º 13
0
 def _get_nonce(self, seq_num):
     padlen = self.fixed_iv_len - len(seq_num)
     padded_seq_num = b"\x00" * padlen + seq_num
     return strxor(padded_seq_num, self.fixed_iv)
Exemplo n.º 14
0
    def _rsaes_oaep_encrypt(self, M, h=None, mgf=None, L=None):
        """
        Internal method providing RSAES-OAEP-ENCRYPT as defined in Sect.
        7.1.1 of RFC 3447. Not intended to be used directly. Please, see
        encrypt() method for type "OAEP".


        Input:
           M  : message to be encrypted, an octet string of length mLen
                where mLen <= k - 2*hLen - 2 (k denotes the length in octets
                of the RSA modulus and hLen the length in octets of the hash
                function output)
           h  : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
                'sha256', 'sha384'). hLen denotes the length in octets of
                the hash function output. 'sha1' is used by default if not
                provided.
           mgf: the mask generation function f : seed, maskLen -> mask
           L  : optional label to be associated with the message; the default
                value for L, if not provided is the empty string

        Output:
           ciphertext, an octet string of length k

        On error, None is returned.
        """
        # The steps below are the one described in Sect. 7.1.1 of RFC 3447.
        # 1) Length Checking
                                                    # 1.a) is not done
        mLen = len(M)
        if h is None:
            h = "sha1"
        if not _hashFuncParams.has_key(h):
            warning("Key._rsaes_oaep_encrypt(): unknown hash function %s.", h)
            return None
        hLen = _hashFuncParams[h][0]
        hFun = _hashFuncParams[h][1]
        k = self.modulusLen / 8
        if mLen > k - 2*hLen - 2:                   # 1.b)
            warning("Key._rsaes_oaep_encrypt(): message too long.")
            return None

        # 2) EME-OAEP encoding
        if L is None:                               # 2.a)
            L = ""
        lHash = hFun(L)
        PS = '\x00'*(k - mLen - 2*hLen - 2)         # 2.b)
        DB = lHash + PS + '\x01' + M                # 2.c)
        seed = randstring(hLen)                     # 2.d)
        if mgf is None:                             # 2.e)
            mgf = lambda x,y: pkcs_mgf1(x,y,h)
        dbMask = mgf(seed, k - hLen - 1)
        maskedDB = strxor(DB, dbMask)               # 2.f)
        seedMask = mgf(maskedDB, hLen)              # 2.g)
        maskedSeed = strxor(seed, seedMask)         # 2.h)
        EM = '\x00' + maskedSeed + maskedDB         # 2.i)

        # 3) RSA Encryption
        m = pkcs_os2ip(EM)                          # 3.a)
        c = self._rsaep(m)                          # 3.b)
        C = pkcs_i2osp(c, k)                        # 3.c)

        return C                                    # 4)
Exemplo n.º 15
0
    def _rsaes_oaep_decrypt(self, C, h=None, mgf=None, L=None):
        """
        Internal method providing RSAES-OAEP-DECRYPT as defined in Sect.
        7.1.2 of RFC 3447. Not intended to be used directly. Please, see
        encrypt() method for type "OAEP".


        Input:
           C  : ciphertext to be decrypted, an octet string of length k, where
                k = 2*hLen + 2 (k denotes the length in octets of the RSA modulus
                and hLen the length in octets of the hash function output)
           h  : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
                'sha256', 'sha384'). 'sha1' is used if none is provided.
           mgf: the mask generation function f : seed, maskLen -> mask
           L  : optional label whose association with the message is to be
                verified; the default value for L, if not provided is the empty
                string.

        Output:
           message, an octet string of length k mLen, where mLen <= k - 2*hLen - 2

        On error, None is returned.
        """
        # The steps below are the one described in Sect. 7.1.2 of RFC 3447.

        # 1) Length Checking
                                                    # 1.a) is not done
        if h is None:
            h = "sha1"
        if not _hashFuncParams.has_key(h):
            warning("Key._rsaes_oaep_decrypt(): unknown hash function %s.", h)
            return None
        hLen = _hashFuncParams[h][0]
        hFun = _hashFuncParams[h][1]
        k = self.modulusLen / 8
        cLen = len(C)
        if cLen != k:                               # 1.b)
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(cLen != k)")
            return None
        if k < 2*hLen + 2:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(k < 2*hLen + 2)")
            return None

        # 2) RSA decryption
        c = pkcs_os2ip(C)                           # 2.a)
        m = self._rsadp(c)                          # 2.b)
        EM = pkcs_i2osp(m, k)                       # 2.c)

        # 3) EME-OAEP decoding
        if L is None:                               # 3.a)
            L = ""
        lHash = hFun(L)
        Y = EM[:1]                                  # 3.b)
        if Y != '\x00':
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(Y is not zero)")
            return None
        maskedSeed = EM[1:1+hLen]
        maskedDB = EM[1+hLen:]
        if mgf is None:
            mgf = lambda x,y: pkcs_mgf1(x, y, h)
        seedMask = mgf(maskedDB, hLen)              # 3.c)
        seed = strxor(maskedSeed, seedMask)         # 3.d)
        dbMask = mgf(seed, k - hLen - 1)            # 3.e)
        DB = strxor(maskedDB, dbMask)               # 3.f)

        # I am aware of the note at the end of 7.1.2 regarding error
        # conditions reporting but the one provided below are for _local_
        # debugging purposes. --arno

        lHashPrime = DB[:hLen]                      # 3.g)
        tmp = DB[hLen:].split('\x01', 1)
        if len(tmp) != 2:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(0x01 separator not found)")
            return None
        PS, M = tmp
        if PS != '\x00'*len(PS):
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(invalid padding string)")
            return None
        if lHash != lHashPrime:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(invalid hash)")
            return None
        return M                                    # 4)
Exemplo n.º 16
0
 def _get_nonce(self, seq_num):
     padlen = self.fixed_iv_len - len(seq_num)
     padded_seq_num = b"\x00" * padlen + seq_num
     return strxor(padded_seq_num, self.fixed_iv)
Exemplo n.º 17
0
    def _rsaes_oaep_decrypt(self, C, h=None, mgf=None, L=None):
        """
        Internal method providing RSAES-OAEP-DECRYPT as defined in Sect.
        7.1.2 of RFC 3447. Not intended to be used directly. Please, see
        encrypt() method for type "OAEP".


        Input:
           C  : ciphertext to be decrypted, an octet string of length k, where
                k = 2*hLen + 2 (k denotes the length in octets of the RSA modulus
                and hLen the length in octets of the hash function output)
           h  : hash function name (in 'md2', 'md4', 'md5', 'sha1', 'tls',
                'sha256', 'sha384'). 'sha1' is used if none is provided.
           mgf: the mask generation function f : seed, maskLen -> mask
           L  : optional label whose association with the message is to be
                verified; the default value for L, if not provided is the empty
                string.

        Output:
           message, an octet string of length k mLen, where mLen <= k - 2*hLen - 2

        On error, None is returned.
        """
        # The steps below are the one described in Sect. 7.1.2 of RFC 3447.

        # 1) Length Checking
        # 1.a) is not done
        if h is None:
            h = "sha1"
        if not _hashFuncParams.has_key(h):
            warning("Key._rsaes_oaep_decrypt(): unknown hash function %s.", h)
            return None
        hLen = _hashFuncParams[h][0]
        hFun = _hashFuncParams[h][1]
        k = self.modulusLen / 8
        cLen = len(C)
        if cLen != k:  # 1.b)
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(cLen != k)")
            return None
        if k < 2 * hLen + 2:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(k < 2*hLen + 2)")
            return None

        # 2) RSA decryption
        c = pkcs_os2ip(C)  # 2.a)
        m = self._rsadp(c)  # 2.b)
        EM = pkcs_i2osp(m, k)  # 2.c)

        # 3) EME-OAEP decoding
        if L is None:  # 3.a)
            L = ""
        lHash = hFun(L)
        Y = EM[:1]  # 3.b)
        if Y != '\x00':
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(Y is not zero)")
            return None
        maskedSeed = EM[1:1 + hLen]
        maskedDB = EM[1 + hLen:]
        if mgf is None:
            mgf = lambda x, y: pkcs_mgf1(x, y, h)
        seedMask = mgf(maskedDB, hLen)  # 3.c)
        seed = strxor(maskedSeed, seedMask)  # 3.d)
        dbMask = mgf(seed, k - hLen - 1)  # 3.e)
        DB = strxor(maskedDB, dbMask)  # 3.f)

        # I am aware of the note at the end of 7.1.2 regarding error
        # conditions reporting but the one provided below are for _local_
        # debugging purposes. --arno

        lHashPrime = DB[:hLen]  # 3.g)
        tmp = DB[hLen:].split('\x01', 1)
        if len(tmp) != 2:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(0x01 separator not found)")
            return None
        PS, M = tmp
        if PS != '\x00' * len(PS):
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(invalid padding string)")
            return None
        if lHash != lHashPrime:
            warning("Key._rsaes_oaep_decrypt(): decryption error. "
                    "(invalid hash)")
            return None
        return M  # 4)