@@ -7,6 +7,9 @@ module Encryption
77 # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
88 def encrypt ( message , p256dh , auth )
99 assert_arguments ( message , p256dh , auth )
10+ # Following RFC8291, messages can't be longer than 3993 bytes long
11+ # so encrypted message do not exceed 4096 bytes
12+ raise ArgumentError , "message is too big" if message . bytesize > 3993
1013
1114 group_name = 'prime256v1'
1215 salt = Random . new . bytes ( 16 )
@@ -33,10 +36,15 @@ def encrypt(message, p256dh, auth)
3336 nonce = HKDF . new ( prk , salt : salt , info : nonce_info ) . next_bytes ( 12 )
3437
3538 ciphertext = encrypt_payload ( message , content_encryption_key , nonce )
39+ # This should never happen if message length <= 3993
40+ raise ArgumentError , "encrypted payload is too big" if ciphertext . bytesize > 4096
3641
3742 serverkey16bn = convert16bit ( server_public_key_bn )
38- rs = ciphertext . bytesize
39- raise ArgumentError , "encrypted payload is too big" if rs > 4096
43+ # According to RFC8188, the final record can be smaller than the record size
44+ # RFC8291 requires encrypted messages to be at most 4096. And the example set the
45+ # RS to 4096. RS can be smaller to 4096 but hardcoding is also following the specs.
46+ # We set RS=4096 to allow testing with the RFC example.
47+ rs = 4096
4048
4149 aes128gcmheader = "#{ salt } " + [ rs ] . pack ( 'N*' ) + [ serverkey16bn . bytesize ] . pack ( 'C*' ) + serverkey16bn
4250
@@ -47,13 +55,14 @@ def encrypt(message, p256dh, auth)
4755 private
4856
4957 def encrypt_payload ( plaintext , content_encryption_key , nonce )
58+ # RFC8291 requires the padding delimiter to be 0x02
59+ plaintext = plaintext + "\x02 "
5060 cipher = OpenSSL ::Cipher . new ( 'aes-128-gcm' )
5161 cipher . encrypt
5262 cipher . key = content_encryption_key
5363 cipher . iv = nonce
5464 text = cipher . update ( plaintext )
55- padding = cipher . update ( "\2 \0 " )
56- e_text = text + padding + cipher . final
65+ e_text = text + cipher . final
5766 e_tag = cipher . auth_tag
5867
5968 e_text + e_tag
0 commit comments