@@ -70,6 +70,34 @@ impl StatelessTransportState {
7070 cipher. encrypt ( nonce, payload, message)
7171 }
7272
73+ /// Construct a message from `plaintext` and write it to the `out` buffer like
74+ /// [`write_message`](Self::write_message). Additionally when computing
75+ /// the authentication tag, mix in the contents of `authtext` which the receiving
76+ /// side will need to also include for successful decryption and authentication.
77+ ///
78+ /// Returns the number of bytes written to `out`.
79+ ///
80+ /// # Errors
81+ ///
82+ /// Will result in `Error::Input` if the size of the output exceeds the max message
83+ /// length in the Noise Protocol (65535 bytes).
84+ pub fn write_message_with_additional_data (
85+ & self ,
86+ nonce : u64 ,
87+ authtext : & [ u8 ] ,
88+ plaintext : & [ u8 ] ,
89+ out : & mut [ u8 ] ,
90+ ) -> Result < usize , Error > {
91+ if !self . initiator && self . pattern . is_oneway ( ) {
92+ return Err ( StateProblem :: OneWay . into ( ) ) ;
93+ } else if plaintext. len ( ) + TAGLEN > MAXMSGLEN || plaintext. len ( ) + TAGLEN > out. len ( ) {
94+ return Err ( Error :: Input ) ;
95+ }
96+
97+ let cipher = if self . initiator { & self . cipherstates . 0 } else { & self . cipherstates . 1 } ;
98+ cipher. encrypt_ad ( nonce, authtext, plaintext, out)
99+ }
100+
73101 /// Read a noise message from `message` and write the payload to the `payload` buffer.
74102 ///
75103 /// Returns the number of bytes written to `payload`.
@@ -97,6 +125,39 @@ impl StatelessTransportState {
97125 }
98126 }
99127
128+ /// Read a noise message from `ciphertext` and write the decrypted payload to `out`
129+ /// buffer like [`read_message`](Self::read_message). Additionally when computing
130+ /// the authentication tag, mix in the contents of `authtext`. This needs to be the
131+ /// same data which was passed to
132+ /// [`write_message_with_additional_data`](Self::write_message_with_additional_data).
133+ ///
134+ /// Returns the number of bytes written to `out`.
135+ ///
136+ /// # Errors
137+ ///
138+ /// Will result in `Error::Input` if the message is more than 65535 bytes.
139+ ///
140+ /// Will result in `Error::Decrypt` if the contents couldn't be decrypted and/or the
141+ /// authentication tag didn't verify.
142+ ///
143+ /// Will result in `StateProblem::Exhausted` if the max nonce overflows.
144+ pub fn read_message_with_additional_data (
145+ & self ,
146+ nonce : u64 ,
147+ authtext : & [ u8 ] ,
148+ ciphertext : & [ u8 ] ,
149+ out : & mut [ u8 ] ,
150+ ) -> Result < usize , Error > {
151+ if ciphertext. len ( ) > MAXMSGLEN {
152+ Err ( Error :: Input )
153+ } else if self . initiator && self . pattern . is_oneway ( ) {
154+ Err ( StateProblem :: OneWay . into ( ) )
155+ } else {
156+ let cipher = if self . initiator { & self . cipherstates . 1 } else { & self . cipherstates . 0 } ;
157+ cipher. decrypt_ad ( nonce, authtext, ciphertext, out)
158+ }
159+ }
160+
100161 /// Generate a new key for the egress symmetric cipher according to Section 4.2
101162 /// of the Noise Specification. Synchronizing timing of rekey between initiator and
102163 /// responder is the responsibility of the application, as described in Section 11.3
0 commit comments