def __init__(self, x, y, curve="p256"): try: self._curve = _curves[curve] except KeyError: raise ValueError("Unknown curve name %s" % str(curve)) self._curve_name = curve modulus_bytes = self.size_in_bytes() context = self._curve.context xb = long_to_bytes(x, modulus_bytes) yb = long_to_bytes(y, modulus_bytes) if len(xb) != modulus_bytes or len(yb) != modulus_bytes: raise ValueError("Incorrect coordinate length") self._point = VoidPointer() result = _ec_lib.ec_ws_new_point(self._point.address_of(), c_uint8_ptr(xb), c_uint8_ptr(yb), c_size_t(modulus_bytes), context.get()) if result: if result == 15: raise ValueError("The EC point does not belong to the curve") raise ValueError("Error %d while instantiating an EC point" % result) # Ensure that object disposal of this Python object will (eventually) # free the memory allocated by the raw library for the EC point self._point = SmartPointer(self._point.get(), _ec_lib.ec_free_point)
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 _compute_mac(self): """Compute MAC without any FSM checks.""" if self._tag: return self._tag # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S self._pad_cache_and_update() self._update(long_to_bytes(8 * self._auth_len, 8)) self._update(long_to_bytes(8 * self._msg_len, 8)) s_tag = self._signer.digest() # Step 6 - Compute T self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len] return self._tag
def to_bytes(self, block_size=0): if self._value < 0: raise ValueError("Conversion only valid for non-negative numbers") result = long_to_bytes(self._value, block_size) if len(result) > block_size > 0: raise ValueError("Value too large to encode") return result
def MGF1(mgfSeed, maskLen, hash_gen): """Mask Generation Function, described in `B.2.1 of RFC8017 <https://tools.ietf.org/html/rfc8017>`_. :param mfgSeed: seed from which the mask is generated :type mfgSeed: byte string :param maskLen: intended length in bytes of the mask :type maskLen: integer :param hash_gen: A module or a hash object from :mod:`crypto.Hash` :type hash_object: :return: the mask, as a *byte string* """ T = b"" for counter in iter_range(ceil_div(maskLen, hash_gen.digest_size)): c = long_to_bytes(counter, 4) hobj = hash_gen.new() hobj.update(mgfSeed + c) T = T + hobj.digest() assert (len(T) >= maskLen) return T[:maskLen]
def _definite_form(length): """Build length octets according to BER/DER definite form. """ if length > 127: encoding = long_to_bytes(length) return bchr(len(encoding) + 128) + encoding return bchr(length)
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 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 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 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
def test3(self): for keylen, taglen, result in self.tv3: key = bchr(0) * (keylen // 8 - 1) + bchr(taglen) C = b("") for i in range(128): S = bchr(0) * i N = long_to_bytes(3 * i + 1, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(S) C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest() N = long_to_bytes(3 * i + 2, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) C += cipher.encrypt(S) + cipher.encrypt() + cipher.digest() N = long_to_bytes(3 * i + 3, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(S) C += cipher.encrypt() + cipher.digest() N = long_to_bytes(385, 12) cipher = AES.new(key, AES.MODE_OCB, nonce=N, mac_len=taglen // 8) cipher.update(C) result2 = cipher.encrypt() + cipher.digest() self.assertEqual(unhexlify(b(result)), result2)
def __imul__(self, scalar): """Multiply this point by a scalar""" if scalar < 0: raise ValueError( "Scalar multiplication is only defined for non-negative integers" ) sb = long_to_bytes(scalar) result = _ec_lib.ec_ws_scalar(self._point.get(), c_uint8_ptr(sb), c_size_t(len(sb)), c_ulonglong(getrandbits(64))) if result: raise ValueError("Error %d during scalar multiplication" % result) return self
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 _start_mac(self): assert (self._mac_status == MacStatus.NOT_STARTED) assert (None not in (self._assoc_len, self._msg_len)) assert (isinstance(self._cache, list)) # Formatting control information and nonce (A.2.1) q = 15 - len(self.nonce) # length of Q, the encoded message length flags = (64 * (self._assoc_len > 0) + 8 * ((self._mac_len - 2) // 2) + (q - 1)) b_0 = struct.pack("B", flags) + self.nonce + long_to_bytes( self._msg_len, q) # Formatting associated data (A.2.2) # Encoded 'a' is concatenated with the associated data 'A' assoc_len_encoded = b'' if self._assoc_len > 0: if self._assoc_len < (2**16 - 2**8): enc_size = 2 elif self._assoc_len < (2**32): assoc_len_encoded = b'\xFF\xFE' enc_size = 4 else: assoc_len_encoded = b'\xFF\xFF' enc_size = 8 assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size) # b_0 and assoc_len_encoded must be processed first self._cache.insert(0, b_0) self._cache.insert(1, assoc_len_encoded) # Process all the data cached so far first_data_to_mac = b"".join(self._cache) self._cache = b"" self._mac_status = MacStatus.PROCESSING_AUTH_DATA self._update(first_data_to_mac)
def init_p521(): p = 0x000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff b = 0x00000051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 order = 0x000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 Gx = 0x000000c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 Gy = 0x0000011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 p521_modulus = long_to_bytes(p, 66) p521_b = long_to_bytes(b, 66) p521_order = long_to_bytes(order, 66) ec_p521_context = VoidPointer() result = _ec_lib.ec_ws_new_context(ec_p521_context.address_of(), c_uint8_ptr(p521_modulus), c_uint8_ptr(p521_b), c_uint8_ptr(p521_order), c_size_t(len(p521_modulus)), c_ulonglong(getrandbits(64))) if result: raise ImportError("Error %d initializing P-521 context" % result) context = SmartPointer(ec_p521_context.get(), _ec_lib.ec_free_context) p521 = _Curve( Integer(p), Integer(b), Integer(order), Integer(Gx), Integer(Gy), None, 521, "1.3.132.0.35", # SEC 2 context, "NIST P-521", "ecdsa-sha2-nistp521") global p521_names _curves.update(dict.fromkeys(p521_names, p521))
def init_p384(): p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef order = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 Gx = 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760aB7 Gy = 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5F p384_modulus = long_to_bytes(p, 48) p384_b = long_to_bytes(b, 48) p384_order = long_to_bytes(order, 48) ec_p384_context = VoidPointer() result = _ec_lib.ec_ws_new_context(ec_p384_context.address_of(), c_uint8_ptr(p384_modulus), c_uint8_ptr(p384_b), c_uint8_ptr(p384_order), c_size_t(len(p384_modulus)), c_ulonglong(getrandbits(64))) if result: raise ImportError("Error %d initializing P-384 context" % result) context = SmartPointer(ec_p384_context.get(), _ec_lib.ec_free_context) p384 = _Curve( Integer(p), Integer(b), Integer(order), Integer(Gx), Integer(Gy), None, 384, "1.3.132.0.34", # SEC 2 context, "NIST P-384", "ecdsa-sha2-nistp384") global p384_names _curves.update(dict.fromkeys(p384_names, p384))
def init_p256(): p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b order = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 p256_modulus = long_to_bytes(p, 32) p256_b = long_to_bytes(b, 32) p256_order = long_to_bytes(order, 32) ec_p256_context = VoidPointer() result = _ec_lib.ec_ws_new_context(ec_p256_context.address_of(), c_uint8_ptr(p256_modulus), c_uint8_ptr(p256_b), c_uint8_ptr(p256_order), c_size_t(len(p256_modulus)), c_ulonglong(getrandbits(64))) if result: raise ImportError("Error %d initializing P-256 context" % result) context = SmartPointer(ec_p256_context.get(), _ec_lib.ec_free_context) p256 = _Curve( Integer(p), Integer(b), Integer(order), Integer(Gx), Integer(Gy), None, 256, "1.2.840.10045.3.1.7", # ANSI X9.62 context, "NIST P-256", "ecdsa-sha2-nistp256") global p256_names _curves.update(dict.fromkeys(p256_names, p256))
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 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 sign(self, msg_hash): """Produce the DSA/ECDSA signature of a message. :parameter msg_hash: The hash that was carried out over the message. The object belongs to the :mod:`crypto.Hash` package. Under mode *'fips-186-3'*, the hash must be a FIPS approved secure hash (SHA-1 or a member of the SHA-2 family), of cryptographic strength appropriate for the DSA key. For instance, a 3072/256 DSA key can only be used in combination with SHA-512. :type msg_hash: hash object :return: The signature as a *byte string* :raise ValueError: if the hash algorithm is incompatible to the (EC)DSA key :raise TypeError: if the (EC)DSA key has no private half """ if not self._valid_hash(msg_hash): raise ValueError("Hash is not sufficiently strong") # Generate the nonce k (critical!) nonce = self._compute_nonce(msg_hash) # Perform signature using the raw API z = Integer.from_bytes(msg_hash.digest()[:self._order_bytes]) sig_pair = self._key._sign(z, nonce) # Encode the signature into a single byte string if self._encoding == 'binary': output = b"".join( [long_to_bytes(x, self._order_bytes) for x in sig_pair]) else: # Dss-sig ::= SEQUENCE { # r INTEGER, # s INTEGER # } # Ecdsa-Sig-Value ::= SEQUENCE { # r INTEGER, # s INTEGER # } output = DerSequence(sig_pair).encode() return output
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 encode(self): """Return the field element, encoded as a 16 byte string.""" return long_to_bytes(self._value, 16)
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 __init__(self, randomness): length = len(randomness) self._idx = 0 # Fix required to get the right K (see how randint() works!) self._randomness = long_to_bytes(bytes_to_long(randomness) - 1, length)
def __init__(self, factory, nonce, mac_len, cipher_params): if factory.block_size != 16: raise ValueError("OCB mode is only available for ciphers" " that operate on 128 bits blocks") self.block_size = 16 """The block size of the underlying cipher, in bytes.""" self.nonce = _copy_bytes(None, None, nonce) """Nonce used for this session.""" if len(nonce) not in range(1, 16): raise ValueError("Nonce must be at most 15 bytes long") if not is_buffer(nonce): raise TypeError("Nonce must be bytes, bytearray or memoryview") self._mac_len = mac_len if not 8 <= mac_len <= 16: raise ValueError("MAC tag must be between 8 and 16 bytes long") # Cache for MAC tag self._mac_tag = None # Cache for unaligned associated data self._cache_A = b"" # Cache for unaligned ciphertext/plaintext self._cache_P = b"" # Allowed transitions after initialization self._next = [ self.update, self.encrypt, self.decrypt, self.digest, self.verify ] # Compute Offset_0 params_without_key = dict(cipher_params) key = params_without_key.pop("key") nonce = (struct.pack('B', self._mac_len << 4 & 0xFF) + b'\x00' * (14 - len(nonce)) + b'\x01' + self.nonce) bottom_bits = bord(nonce[15]) & 0x3F # 6 bits, 0..63 top_bits = bord(nonce[15]) & 0xC0 # 2 bits ktop_cipher = factory.new(key, factory.MODE_ECB, **params_without_key) ktop = ktop_cipher.encrypt(struct.pack('15sB', nonce[:15], top_bits)) stretch = ktop + strxor(ktop[:8], ktop[1:9]) # 192 bits offset_0 = long_to_bytes( bytes_to_long(stretch) >> (64 - bottom_bits), 24)[8:] # Create low-level cipher instance raw_cipher = factory._create_base_cipher(cipher_params) if cipher_params: raise TypeError("Unknown keywords: " + str(cipher_params)) self._state = VoidPointer() result = _raw_ocb_lib.OCB_start_operation(raw_cipher.get(), offset_0, c_size_t(len(offset_0)), self._state.address_of()) if result: raise ValueError("Error %d while instantiating the OCB mode" % result) # Ensure that object disposal of this Python object will (eventually) # free the memory allocated by the raw library for the cipher mode self._state = SmartPointer(self._state.get(), _raw_ocb_lib.OCB_stop_operation) # Memory allocated for the underlying block cipher is now owed # by the cipher mode raw_cipher.release()
def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c): self.block_size = factory.block_size if self.block_size != 16: raise ValueError("GCM mode is only available for ciphers" " that operate on 128 bits blocks") if len(nonce) == 0: raise ValueError("Nonce cannot be empty") if not is_buffer(nonce): raise TypeError("Nonce must be bytes, bytearray or memoryview") # See NIST SP 800 38D, 5.2.1.1 if len(nonce) > 2**64 - 1: raise ValueError("Nonce exceeds maximum length") self.nonce = _copy_bytes(None, None, nonce) """Nonce""" self._factory = factory self._key = _copy_bytes(None, None, key) self._tag = None # Cache for MAC tag self._mac_len = mac_len if not (4 <= mac_len <= 16): raise ValueError("Parameter 'mac_len' must be in the range 4..16") # Allowed transitions after initialization self._next = [ self.update, self.encrypt, self.decrypt, self.digest, self.verify ] self._no_more_assoc_data = False # Length of associated data self._auth_len = 0 # Length of the ciphertext or plaintext self._msg_len = 0 # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H # See also Algorithm 5 (decryption) hash_subkey = factory.new(key, self._factory.MODE_ECB, **cipher_params).encrypt(b'\x00' * 16) # Step 2 - Compute J0 if len(self.nonce) == 12: j0 = self.nonce + b"\x00\x00\x00\x01" else: fill = (16 - (len(nonce) % 16)) % 16 + 8 ghash_in = (self.nonce + b'\x00' * fill + long_to_bytes(8 * len(nonce), 8)) j0 = _GHASH(hash_subkey, ghash_c).update(ghash_in).digest() # Step 3 - Prepare GCTR cipher for encryption/decryption nonce_ctr = j0[:12] iv_ctr = (bytes_to_long(j0) + 1) & 0xFFFFFFFF self._cipher = factory.new(key, self._factory.MODE_CTR, initial_value=iv_ctr, nonce=nonce_ctr, **cipher_params) # Step 5 - Bootstrat GHASH self._signer = _GHASH(hash_subkey, ghash_c) # Step 6 - Prepare GCTR cipher for GMAC self._tag_cipher = factory.new(key, self._factory.MODE_CTR, initial_value=j0, nonce=b"", **cipher_params) # Cache for data to authenticate self._cache = b"" self._status = MacStatus.PROCESSING_AUTH_DATA
def _create_ctr_cipher(factory, **kwargs): """Instantiate a cipher object that performs CTR encryption/decryption. :Parameters: factory : module The underlying block cipher, a module from ``Crypto.Cipher``. :Keywords: nonce : bytes/bytearray/memoryview The fixed part at the beginning of the counter block - the rest is the counter number that gets increased when processing the next block. The nonce must be such that no two messages are encrypted under the same key and the same nonce. The nonce must be shorter than the block size (it can have zero length; the counter is then as long as the block). If this parameter is not present, a random nonce will be created with length equal to half the block size. No random nonce shorter than 64 bits will be created though - you must really think through all security consequences of using such a short block size. initial_value : posive integer or bytes/bytearray/memoryview The initial value for the counter. If not present, the cipher will start counting from 0. The value is incremented by one for each block. The counter number is encoded in big endian mode. counter : object Instance of ``Crypto.Util.Counter``, which allows full customization of the counter block. This parameter is incompatible to both ``nonce`` and ``initial_value``. Any other keyword will be passed to the underlying block cipher. See the relevant documentation for details (at least ``key`` will need to be present). """ cipher_state = factory._create_base_cipher(kwargs) counter = kwargs.pop("counter", None) nonce = kwargs.pop("nonce", None) initial_value = kwargs.pop("initial_value", None) if kwargs: raise TypeError("Invalid parameters for CTR mode: %s" % str(kwargs)) if counter is not None and (nonce, initial_value) != (None, None): raise TypeError("'counter' and 'nonce'/'initial_value'" " are mutually exclusive") if counter is None: # Crypto.Util.Counter is not used if nonce is None: if factory.block_size < 16: raise TypeError("Impossible to create a safe nonce for short" " block sizes") nonce = get_random_bytes(factory.block_size // 2) else: if len(nonce) >= factory.block_size: raise ValueError("Nonce is too long") # What is not nonce is counter counter_len = factory.block_size - len(nonce) if initial_value is None: initial_value = 0 if isinstance(initial_value, int): if (1 << (counter_len * 8)) - 1 < initial_value: raise ValueError("Initial counter value is too large") initial_counter_block = nonce + long_to_bytes( initial_value, counter_len) else: if len(initial_value) != counter_len: raise ValueError( "Incorrect length for counter byte string (%d bytes, expected %d)" % (len(initial_value), counter_len)) initial_counter_block = nonce + initial_value return CtrMode( cipher_state, initial_counter_block, len(nonce), # prefix counter_len, False) # little_endian # Crypto.Util.Counter is used # 'counter' used to be a callable object, but now it is # just a dictionary for backward compatibility. _counter = dict(counter) try: counter_len = _counter.pop("counter_len") prefix = _counter.pop("prefix") suffix = _counter.pop("suffix") initial_value = _counter.pop("initial_value") little_endian = _counter.pop("little_endian") except KeyError: raise TypeError("Incorrect counter object" " (use Crypto.Util.Counter.new)") # Compute initial counter block words = [] while initial_value > 0: words.append(struct.pack('B', initial_value & 255)) initial_value >>= 8 words += [b'\x00'] * max(0, counter_len - len(words)) if not little_endian: words.reverse() initial_counter_block = prefix + b"".join(words) + suffix if len(initial_counter_block) != factory.block_size: raise ValueError("Size of the counter block (%d bytes) must match" " block size (%d)" % (len(initial_counter_block), factory.block_size)) return CtrMode(cipher_state, initial_counter_block, len(prefix), counter_len, little_endian)
def _int2octets(self, int_mod_q): """See 2.3.3 in RFC6979""" assert 0 < int_mod_q < self._order return long_to_bytes(int_mod_q, self._order_bytes)
def _shift_bytes(bs, xor_lsb=0): num = (bytes_to_long(bs) << 1) ^ xor_lsb return long_to_bytes(num, len(bs))[-len(bs):]
def decrypt(self, ciphertext): """Decrypt a message with PKCS#1 OAEP. :param ciphertext: The encrypted message. :type ciphertext: bytes/bytearray/memoryview :returns: The original message (plaintext). :rtype: bytes :raises ValueError: if the ciphertext has the wrong length, or if decryption fails the integrity check (in which case, the decryption key is probably wrong). :raises TypeError: if the RSA key has no private half (i.e. you are trying to decrypt using a public key). """ # See 7.1.2 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 # Step 1b and 1c if len(ciphertext) != k or k < hLen + 2: raise ValueError("Ciphertext with incorrect length.") # Step 2a (O2SIP) ct_int = bytes_to_long(ciphertext) # Step 2b (RSADP) m_int = self._key._decrypt(ct_int) # Complete step 2c (I2OSP) em = long_to_bytes(m_int, k) # Step 3a lHash = self._hashObj.new(self._label).digest() # Step 3b y = em[0] # y must be 0, but we MUST NOT check it here in order not to # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143) maskedSeed = em[1:hLen + 1] maskedDB = em[hLen + 1:] # Step 3c seedMask = self._mgf(maskedDB, hLen) # Step 3d seed = strxor(maskedSeed, seedMask) # Step 3e dbMask = self._mgf(seed, k - hLen - 1) # Step 3f db = strxor(maskedDB, dbMask) # Step 3g one_pos = db[hLen:].find(b'\x01') lHash1 = db[:hLen] invalid = bord(y) | int(one_pos < 0) hash_compare = strxor(lHash1, lHash) for x in hash_compare: invalid |= bord(x) for x in db[hLen:one_pos]: invalid |= bord(x) if invalid != 0: raise ValueError("Incorrect decryption.") # Step 4 return db[hLen + one_pos + 1:]