def _check_encryption(self, rsaObj): plaintext = a2b_hex(self.plaintext) ciphertext = a2b_hex(self.ciphertext) # Test encryption new_ciphertext2 = rsaObj._encrypt(bytes_to_long(plaintext)) self.assertEqual(bytes_to_long(ciphertext), new_ciphertext2)
def _check_decryption(self, rsaObj): plaintext = bytes_to_long(a2b_hex(self.plaintext)) ciphertext = bytes_to_long(a2b_hex(self.ciphertext)) # Test plain decryption new_plaintext = rsaObj._decrypt(ciphertext) self.assertEqual(plaintext, new_plaintext)
def _test_signing(self, dsaObj): k = bytes_to_long(a2b_hex(self.k)) m_hash = bytes_to_long(a2b_hex(self.m_hash)) r = bytes_to_long(a2b_hex(self.r)) s = bytes_to_long(a2b_hex(self.s)) (r_out, s_out) = dsaObj._sign(m_hash, k) self.assertEqual((r, s), (r_out, s_out))
def _check_public_key(self, dsaObj): k = bytes_to_long(a2b_hex(self.k)) m_hash = bytes_to_long(a2b_hex(self.m_hash)) # Check capabilities self.assertEqual(0, dsaObj.has_private()) self.assertEqual(1, dsaObj.can_sign()) self.assertEqual(0, dsaObj.can_encrypt()) # Check that private parameters are all missing self.assertEqual(0, hasattr(dsaObj, 'x')) # Sanity check key data self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1 # Public-only key objects should raise an error when .sign() is called self.assertRaises(TypeError, dsaObj._sign, m_hash, k) # Check __eq__ and __ne__ self.assertEqual(dsaObj.publickey() == dsaObj.publickey(), True) # assert_ self.assertEqual(dsaObj.publickey() != dsaObj.publickey(), False) # failIf
def xy(self): modulus_bytes = self.size_in_bytes() xb = bytearray(modulus_bytes) yb = bytearray(modulus_bytes) result = _ec_lib.ec_ws_get_xy(c_uint8_ptr(xb), c_uint8_ptr(yb), c_size_t(modulus_bytes), self._point.get()) if result: raise ValueError("Error %d while encoding an EC point" % result) return (Integer(bytes_to_long(xb)), Integer(bytes_to_long(yb)))
def setUp(self): global RSA, Random, bytes_to_long from crypto.PublicKey import RSA from crypto import Random from crypto.Util.number import bytes_to_long, inverse self.n = bytes_to_long(a2b_hex(self.modulus)) self.p = bytes_to_long(a2b_hex(self.prime_factor)) # Compute q, d, and u from n, e, and p self.q = self.n // self.p self.d = inverse(self.e, (self.p-1)*(self.q-1)) self.u = inverse(self.p, self.q) # u = e**-1 (mod q) self.rsa = RSA
def getrandbits(self, k): """Return an integer with k random bits.""" if self._randfunc is None: self._randfunc = Random.new().read mask = (1 << k) - 1 return mask & bytes_to_long(self._randfunc(ceil_div(k, 8)))
def sign(self, msg_hash): """Create the PKCS#1 v1.5 signature of a message. This function is also called ``RSASSA-PKCS1-V1_5-SIGN`` and it is specified in `section 8.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-36>`_. :parameter msg_hash: This is an object from the :mod:`Crypto.Hash` package. It has been used to digest the message to sign. :type msg_hash: hash object :return: the signature encoded as a *byte string*. :raise ValueError: if the RSA key is not long enough for the given hash algorithm. :raise TypeError: if the RSA key has no private half. """ # See 8.2.1 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits,8) # Convert from bits to bytes # Step 1 em = _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def _check_public_key(self, rsaObj): ciphertext = a2b_hex(self.ciphertext) # Check capabilities self.assertEqual(0, rsaObj.has_private()) # Check rsaObj.[ne] -> rsaObj.[ne] mapping self.assertEqual(rsaObj.n, rsaObj.n) self.assertEqual(rsaObj.e, rsaObj.e) # Check that private parameters are all missing self.assertEqual(0, hasattr(rsaObj, 'd')) self.assertEqual(0, hasattr(rsaObj, 'p')) self.assertEqual(0, hasattr(rsaObj, 'q')) self.assertEqual(0, hasattr(rsaObj, 'u')) # Sanity check key data self.assertEqual(1, rsaObj.e > 1) # e > 1 # Public keys should not be able to sign or decrypt self.assertRaises(TypeError, rsaObj._decrypt, bytes_to_long(ciphertext)) # Check __eq__ and __ne__ self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_ self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
def test_construct_4tuple(self): """DSA (default implementation) constructed key (4-tuple)""" (y, g, p, q) = [ bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q) ] dsaObj = self.dsa.construct((y, g, p, q)) self._test_verification(dsaObj)
def test_construct_bad_key5(self): (y, g, p, q, x) = [ bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x) ] tup = (y, g, p, q, x + 1) self.assertRaises(ValueError, self.dsa.construct, tup) tup = (y, g, p, q, q + 10) self.assertRaises(ValueError, self.dsa.construct, tup)
def _create_ctr_cipher(self, v): """Create a new CTR cipher from V in SIV mode""" v_int = bytes_to_long(v) q = v_int & 0xFFFFFFFFFFFFFFFF7FFFFFFF7FFFFFFF return self._factory.new(self._subkey_cipher, self._factory.MODE_CTR, initial_value=q, nonce=b"", **self._cipher_params)
def verify(self, msg_hash, signature): """Check if the PKCS#1 v1.5 signature over a message is valid. This function is also called ``RSASSA-PKCS1-V1_5-VERIFY`` and it is specified in `section 8.2.2 of RFC8037 <https://tools.ietf.org/html/rfc8017#page-37>`_. :parameter msg_hash: The hash that was carried out over the message. This is an object belonging to the :mod:`Crypto.Hash` module. :type parameter: hash object :parameter signature: The signature that needs to be validated. :type signature: byte string :raise ValueError: if the signature is not valid. """ # See 8.2.2 in RFC3447 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(signature) != k: raise ValueError("Invalid signature") # Step 2a (O2SIP) signature_int = bytes_to_long(signature) # Step 2b (RSAVP1) em_int = self._key._encrypt(signature_int) # Step 2c (I2OSP) em1 = long_to_bytes(em_int, k) # Step 3 try: possible_em1 = [ _EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, True) ] # MD2/4/5 hashes always require NULL params in AlgorithmIdentifier. # For all others, it is optional. try: algorithm_is_md = msg_hash.oid.startswith('1.2.840.113549.2.') except AttributeError: algorithm_is_md = False if not algorithm_is_md: # MD2/MD4/MD5 possible_em1.append(_EMSA_PKCS1_V1_5_ENCODE(msg_hash, k, False)) except ValueError: raise ValueError("Invalid signature") # Step 4 # By comparing the full encodings (as opposed to checking each # of its components one at a time) we avoid attacks to the padding # scheme like Bleichenbacher's (see http://www.mail-archive.com/[email protected]/msg06537). # if em1 not in possible_em1: raise ValueError("Invalid signature") pass
def _decodeLen(self, s): """Decode DER length octets from a file.""" length = s.read_byte() if length <= 127: return length payloadLength = bytes_to_long(s.read(length & 0x7F)) # According to DER (but not BER) the long form is used # only when the length doesn't fit into 7 bits. if payloadLength <= 127: raise ValueError("Not a DER length tag (but still valid BER).") return payloadLength
def encrypt(self, message): """Encrypt a message with PKCS#1 OAEP. :param message: The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 2, minus twice the hash output size. For instance, if you use RSA 2048 and SHA-256, the longest message you can encrypt is 190 byte long. :type message: bytes/bytearray/memoryview :returns: The ciphertext, as large as the RSA modulus. :rtype: bytes :raises ValueError: if the message is too long. """ # See 7.1.1 in RFC3447 modBits = crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes hLen = self._hashObj.digest_size mLen = len(message) # Step 1b ps_len = k - mLen - 2 * hLen - 2 if ps_len < 0: raise ValueError("Plaintext is too long.") # Step 2a lHash = self._hashObj.new(self._label).digest() # Step 2b ps = b'\x00' * ps_len # Step 2c db = lHash + ps + b'\x01' + _copy_bytes(None, None, message) # Step 2d ros = self._randfunc(hLen) # Step 2e dbMask = self._mgf(ros, k - hLen - 1) # Step 2f maskedDB = strxor(db, dbMask) # Step 2g seedMask = self._mgf(maskedDB, hLen) # Step 2h maskedSeed = strxor(ros, seedMask) # Step 2i em = b'\x00' + maskedSeed + maskedDB # Step 3a (OS2IP) em_int = bytes_to_long(em) # Step 3b (RSAEP) m_int = self._key._encrypt(em_int) # Step 3c (I2OSP) c = long_to_bytes(m_int, k) return c
def _exercise_primitive(self, rsaObj): # Since we're using a randomly-generated key, we can't check the test # vector, but we can make sure encryption and decryption are inverse # operations. ciphertext = bytes_to_long(a2b_hex(self.ciphertext)) # Test decryption plaintext = rsaObj._decrypt(ciphertext) # Test encryption (2 arguments) new_ciphertext2 = rsaObj._encrypt(plaintext) self.assertEqual(ciphertext, new_ciphertext2)
def convert_tv(self, tv, as_longs=0): """Convert a test vector from textual form (hexadecimal ascii to either integers or byte strings.""" key_comps = 'p', 'g', 'y', 'x' tv2 = {} for c in list(tv.keys()): tv2[c] = a2b_hex(tv[c]) if as_longs or c in key_comps or c in ('sig1', 'sig2'): tv2[c] = bytes_to_long(tv2[c]) tv2['key'] = [] for c in key_comps: tv2['key'] += [tv2[c]] del tv2[c] return tv2
def testVerify2(self): # Verify that decryption fails if ciphertext is not as long as # RSA modulus cipher = PKCS.new(self.key1024) self.assertRaises(ValueError, cipher.decrypt, '\x00' * 127, "---") self.assertRaises(ValueError, cipher.decrypt, '\x00' * 129, "---") # Verify that decryption fails if there are less then 8 non-zero padding # bytes pt = b('\x00\x02' + '\xFF' * 7 + '\x00' + '\x45' * 118) pt_int = bytes_to_long(pt) ct_int = self.key1024._encrypt(pt_int) ct = long_to_bytes(ct_int, 128) self.assertEqual("---", cipher.decrypt(ct, "---"))
def _decodeLen(self, s): """Decode DER length octets from a file.""" length = s.read_byte() if length > 127: encoded_length = s.read(length & 0x7F) if bord(encoded_length[0]) == 0: raise ValueError("Invalid DER: length has leading zero") length = bytes_to_long(encoded_length) if length <= 127: raise ValueError( "Invalid DER: length in long form but smaller than 128") return length
def __init__(self, encoded_value): """Initialize the element to a certain value. The value passed as parameter is internally encoded as a 128-bit integer, where each bit represents a polynomial coefficient. The LSB is the constant coefficient. """ if isinstance(encoded_value, int): self._value = encoded_value elif len(encoded_value) == 16: self._value = bytes_to_long(encoded_value) else: raise ValueError( "The encoded value must be an integer or a 16 byte string")
def encrypt(self, message): """Produce the PKCS#1 v1.5 encryption of a message. This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in `section 7.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#page-28>`_. :param message: The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 11. :type message: bytes/bytearray/memoryview :Returns: A byte string, the ciphertext in which the message is encrypted. It is as long as the RSA modulus (in bytes). :Raises ValueError: If the RSA key length is not sufficiently long to deal with the given message. """ # See 7.2.1 in RFC8017 modBits = Crypto.Util.number.size(self._key.n) k = ceil_div(modBits, 8) # Convert from bits to bytes mLen = len(message) # Step 1 if mLen > k - 11: raise ValueError("Plaintext is too long.") # Step 2a ps = [] while len(ps) != k - mLen - 3: new_byte = self._randfunc(1) if bord(new_byte[0]) == 0x00: continue ps.append(new_byte) ps = b"".join(ps) assert (len(ps) == k - mLen - 3) # Step 2b em = b'\x00\x02' + ps + b'\x00' + _copy_bytes(None, None, message) # Step 3a (OS2IP) em_int = bytes_to_long(em) # Step 3b (RSAEP) m_int = self._key._encrypt(em_int) # Step 3c (I2OSP) c = long_to_bytes(m_int, k) return c
def __init__(self, factory, key, nonce, mac_len, cipher_params): """EAX cipher mode""" self.block_size = factory.block_size """The block size of the underlying cipher, in bytes.""" self.nonce = _copy_bytes(None, None, nonce) """The nonce originally used to create the object.""" self._mac_len = mac_len self._mac_tag = None # Cache for MAC tag # Allowed transitions after initialization self._next = [ self.update, self.encrypt, self.decrypt, self.digest, self.verify ] # MAC tag length if not (4 <= self._mac_len <= self.block_size): raise ValueError("Parameter 'mac_len' must not be larger than %d" % self.block_size) # Nonce cannot be empty and must be a byte string if len(self.nonce) == 0: raise ValueError("Nonce cannot be empty in EAX mode") if not is_buffer(nonce): raise TypeError("nonce must be bytes, bytearray or memoryview") self._omac = [ CMAC.new(key, b'\x00' * (self.block_size - 1) + struct.pack('B', i), ciphermod=factory, cipher_params=cipher_params) for i in range(0, 3) ] # Compute MAC of nonce self._omac[0].update(self.nonce) self._signer = self._omac[1] # MAC of the nonce is also the initial counter for CTR encryption counter_int = bytes_to_long(self._omac[0].digest()) self._cipher = factory.new(key, factory.MODE_CTR, initial_value=counter_int, nonce=b"", **cipher_params)
def verify(self, msg_hash, signature): """Check if the PKCS#1 PSS signature over a message is valid. This function is also called ``RSASSA-PSS-VERIFY`` and it is specified in `section 8.1.2 of RFC8037 <https://tools.ietf.org/html/rfc8017#section-8.1.2>`_. :parameter msg_hash: The hash that was carried out over the message. This is an object belonging to the :mod:`crypto.Hash` module. :type parameter: hash object :parameter signature: The signature that needs to be validated. :type signature: bytes :raise ValueError: if the signature is not valid. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc: mgf = self._mgfunc else: mgf = lambda x, y: MGF1(x, y, msg_hash) modBits = crypto.Util.number.size(self._key.n) # See 8.1.2 in RFC3447 k = ceil_div(modBits, 8) # Convert from bits to bytes # Step 1 if len(signature) != k: raise ValueError("Incorrect signature") # Step 2a (O2SIP) signature_int = bytes_to_long(signature) # Step 2b (RSAVP1) em_int = self._key._encrypt(signature_int) # Step 2c (I2OSP) emLen = ceil_div(modBits - 1, 8) em = long_to_bytes(em_int, emLen) # Step 3/4 _EMSA_PSS_VERIFY(msg_hash, em, modBits - 1, mgf, sLen)
def monty_pow(base, exp, modulus): max_len = len(long_to_bytes(max(base, exp, modulus))) base_b, exp_b, modulus_b = [ long_to_bytes(x, max_len) for x in (base, exp, modulus) ] out = create_string_buffer(max_len) error = _raw_montgomery.monty_pow(base_b, exp_b, modulus_b, out, c_size_t(max_len), c_ulonglong(32)) if error == 2: raise ExceptionModulus() if error: raise ValueError("monty_pow failed with error: %d" % error) result = bytes_to_long(get_raw_buffer(out)) return result
def sign(self, msg_hash): """Create the PKCS#1 PSS signature of a message. This function is also called ``RSASSA-PSS-SIGN`` and it is specified in `section 8.1.1 of RFC8017 <https://tools.ietf.org/html/rfc8017#section-8.1.1>`_. :parameter msg_hash: This is an object from the :mod:`crypto.Hash` package. It has been used to digest the message to sign. :type msg_hash: hash object :return: the signature encoded as a *byte string*. :raise ValueError: if the RSA key is not long enough for the given hash algorithm. :raise TypeError: if the RSA key has no private half. """ # Set defaults for salt length and mask generation function if self._saltLen is None: sLen = msg_hash.digest_size else: sLen = self._saltLen if self._mgfunc is None: mgf = lambda x, y: MGF1(x, y, msg_hash) else: mgf = self._mgfunc modBits = crypto.Util.number.size(self._key.n) # See 8.1.1 in RFC3447 k = ceil_div(modBits, 8) # k is length in bytes of the modulus # Step 1 em = _EMSA_PSS_ENCODE(msg_hash, modBits - 1, self._randfunc, mgf, sLen) # Step 2a (OS2IP) em_int = bytes_to_long(em) # Step 2b (RSASP1) m_int = self._key._decrypt(em_int) # Step 2c (I2OSP) signature = long_to_bytes(m_int, k) return signature
def inplace_pow(self, exponent, modulus=None): exp_value = int(exponent) if exp_value < 0: raise ValueError("Exponent must not be negative") # No modular reduction if modulus is None: self._value = pow(self._value, exp_value) return self # With modular reduction mod_value = int(modulus) if mod_value < 0: raise ValueError("Modulus must be positive") if mod_value == 0: raise ZeroDivisionError("Modulus cannot be zero") # C extension only works with odd moduli if (mod_value & 1) == 0: self._value = pow(self._value, exp_value, mod_value) return self max_len = len(long_to_bytes(max(self._value, exp_value, mod_value))) base_b = long_to_bytes(self._value, max_len) exp_b = long_to_bytes(exp_value, max_len) modulus_b = long_to_bytes(mod_value, max_len) out = create_string_buffer(max_len) error = _raw_montgomery.monty_pow(base_b, exp_b, modulus_b, out, c_size_t(max_len), c_ulonglong(getrandbits(64))) if error: raise ValueError("monty_pow failed with error: %d" % error) result = bytes_to_long(get_raw_buffer(out)) self._value = result return self
"Signature Verification 186-3", { 'shaalg' : lambda x: x, 'd' : lambda x: int(x), 'result' : lambda x: x }) for count, tv in enumerate(test_vectors_verify): if isinstance(tv, str): continue if hasattr(tv, "n"): modulus = tv.n continue hash_module = load_hash_by_name(tv.shaalg.upper()) hash_obj = hash_module.new(tv.msg) public_key = RSA.construct([bytes_to_long(x) for x in (modulus, tv.e)]) verifier = pkcs1_15.new(public_key) def positive_test(self, hash_obj=hash_obj, verifier=verifier, signature=tv.s): verifier.verify(hash_obj, signature) def negative_test(self, hash_obj=hash_obj, verifier=verifier, signature=tv.s): self.assertRaises(ValueError, verifier.verify, hash_obj, signature) if tv.result == 'f': setattr(FIPS_PKCS1_Verify_Tests_KAT, "test_negative_%d" % count, negative_test) else: setattr(FIPS_PKCS1_Verify_Tests_KAT, "test_positive_%d" % count, positive_test) class FIPS_PKCS1_Sign_Tests(unittest.TestCase):
def _double(self, bs): doubled = bytes_to_long(bs) << 1 if bord(bs[0]) & 0x80: doubled ^= 0x87 return long_to_bytes(doubled, len(bs))[-len(bs):]
def from_bytes(cls, byte_string): return cls(bytes_to_long(byte_string))
def _shift_bytes(bs, xor_lsb=0): num = (bytes_to_long(bs) << 1) ^ xor_lsb return long_to_bytes(num, len(bs))[-len(bs):]