@@ -39,8 +39,8 @@ function HKDF_expand(prk, info, l) {
3939 return output . slice ( 0 , l ) ;
4040}
4141
42- function HKDF ( salt , ikm , info , l ) {
43- return HKDF_expand ( HKDF_extract ( salt , ikm ) , info , l ) ;
42+ function HKDF ( salt , ikm , info , len ) {
43+ return HKDF_expand ( HKDF_extract ( salt , ikm ) , info , len ) ;
4444}
4545
4646function info ( base , context ) {
@@ -98,38 +98,36 @@ function extractDH(keyid, dh, mode) {
9898}
9999
100100function extractSecretAndContext ( params , mode ) {
101- var secret ;
102- var context = new Buffer ( 0 ) ;
101+ var result = { secret : null , context : new Buffer ( 0 ) } ;
103102 if ( params . key ) {
104- secret = base64 . decode ( params . key ) ;
105- if ( secret . length !== KEY_LENGTH ) {
103+ result . secret = base64 . decode ( params . key ) ;
104+ if ( result . secret . length !== KEY_LENGTH ) {
106105 throw new Error ( 'An explicit key must be ' + KEY_LENGTH + ' bytes' ) ;
107106 }
108107 } else if ( params . dh ) { // receiver/decrypt
109- var r = extractDH ( params . keyid , params . dh , mode ) ;
110- secret = r . secret ;
111- context = r . context ;
108+ result = extractDH ( params . keyid , params . dh , mode ) ;
112109 } else if ( params . keyid ) {
113- secret = savedKeys [ params . keyid ] ;
110+ result . secret = savedKeys [ params . keyid ] ;
114111 }
115- if ( ! secret ) {
112+ if ( ! result . secret ) {
116113 throw new Error ( 'Unable to determine key' ) ;
117114 }
118115 if ( params . authSecret ) {
119- secret = HKDF ( base64 . decode ( params . authSecret ) , secret ,
116+ result . secret = HKDF ( base64 . decode ( params . authSecret ) , result . secret ,
120117 info ( 'auth' , new Buffer ( 0 ) ) , SHA_256_LENGTH ) ;
121118 }
122- return { secret : secret , context : context } ;
119+ return result ;
123120}
124121
125122function deriveKeyAndNonce ( params , mode ) {
126123 var salt = extractSalt ( params . salt ) ;
127124 var s = extractSecretAndContext ( params , mode ) ;
128125 var prk = HKDF_extract ( salt , s . secret ) ;
129- return {
126+ var result = {
130127 key : HKDF_expand ( prk , info ( 'aesgcm128' , s . context ) , KEY_LENGTH ) ,
131128 nonce : HKDF_expand ( prk , info ( 'nonce' , s . context ) , NONCE_LENGTH )
132129 } ;
130+ return result ;
133131}
134132
135133function determineRecordSize ( params ) {
@@ -232,12 +230,22 @@ function encrypt(buffer, params) {
232230 var rs = determineRecordSize ( params ) ;
233231 var start = 0 ;
234232 var result = new Buffer ( 0 ) ;
233+ var pad = isNaN ( parseInt ( params . pad , 10 ) ) ? 0 : parseInt ( params . pad , 10 ) ;
235234
235+ // Note the <= here ensures that we write out a padding-only block at the end
236+ // of a buffer.
236237 for ( var i = 0 ; start <= buffer . length ; ++ i ) {
237- var end = Math . min ( start + rs - 1 , buffer . length ) ;
238- var block = encryptRecord ( key , i , buffer . slice ( start , end ) ) ;
238+ // Pad so that at least one data byte is in a block.
239+ var recordPad = Math . min ( 255 , Math . min ( rs - 2 , pad ) ) ;
240+ pad -= recordPad ;
241+
242+ var end = Math . min ( start + rs - 1 - recordPad , buffer . length ) ;
243+ var block = encryptRecord ( key , i , buffer . slice ( start , end ) , recordPad ) ;
239244 result = Buffer . concat ( [ result , block ] ) ;
240- start += rs - 1 ;
245+ start += rs - 1 - recordPad ;
246+ }
247+ if ( pad ) {
248+ throw new Error ( 'Unable to pad by requested amount, ' + pad + ' remaining' ) ;
241249 }
242250 return result ;
243251}
0 commit comments