@@ -278,15 +278,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
278278 return ( 0 );
279279 }
280280
281- #if defined(MBEDTLS_GCM_C )
282- if ( ctx -> cipher_info -> mode == MBEDTLS_MODE_GCM )
283- {
284- * olen = ilen ;
285- return mbedtls_gcm_update ( (mbedtls_gcm_context * ) ctx -> cipher_ctx , ilen , input ,
286- output );
287- }
288- #endif
289-
290281 if ( 0 == block_size )
291282 {
292283 return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT ;
@@ -298,6 +289,84 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
298289 return ( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
299290 }
300291
292+ #if defined(MBEDTLS_GCM_C )
293+ if ( ctx -> cipher_info -> mode == MBEDTLS_MODE_GCM )
294+ {
295+ size_t copy_len = 0 ;
296+
297+ /*
298+ * If there is not enough data for a full block, cache it.
299+ */
300+ if ( ( ctx -> operation == MBEDTLS_DECRYPT && ilen + ctx -> unprocessed_len <= block_size ) ||
301+ ( ctx -> operation == MBEDTLS_ENCRYPT && ilen + ctx -> unprocessed_len < block_size ) )
302+ {
303+ memcpy ( & ( ctx -> unprocessed_data [ctx -> unprocessed_len ] ), input ,
304+ ilen );
305+
306+ ctx -> unprocessed_len += ilen ;
307+ return ( 0 );
308+ }
309+
310+ /*
311+ * Process cached data first
312+ */
313+ if ( ctx -> unprocessed_len != 0 )
314+ {
315+ copy_len = block_size - ctx -> unprocessed_len ;
316+
317+ memcpy ( & ( ctx -> unprocessed_data [ctx -> unprocessed_len ] ), input ,
318+ copy_len );
319+
320+ ctx -> unprocessed_len += copy_len ;
321+
322+ if ( 0 != ( ret = mbedtls_gcm_update ( (mbedtls_gcm_context * ) ctx -> cipher_ctx ,
323+ ctx -> unprocessed_len , ctx -> unprocessed_data , output ) ) )
324+ {
325+ return ( ret );
326+ }
327+
328+ * olen += block_size ;
329+ output += block_size ;
330+ ctx -> unprocessed_len = 0 ;
331+
332+ input += copy_len ;
333+ ilen -= copy_len ;
334+ }
335+
336+ /*
337+ * Cache final, incomplete block
338+ */
339+ if ( 0 != ilen )
340+ {
341+ copy_len = ilen % block_size ;
342+ if ( copy_len == 0 && ctx -> operation == MBEDTLS_DECRYPT )
343+ copy_len = block_size ;
344+
345+ memcpy ( ctx -> unprocessed_data , & ( input [ilen - copy_len ] ),
346+ copy_len );
347+
348+ ctx -> unprocessed_len += copy_len ;
349+ ilen -= copy_len ;
350+ }
351+
352+ /*
353+ * Process remaining full blocks
354+ */
355+ if ( ilen )
356+ {
357+ if ( 0 != ( ret = mbedtls_gcm_update ( (mbedtls_gcm_context * ) ctx -> cipher_ctx ,
358+ ilen , input , output ) ) )
359+ {
360+ return ( ret );
361+ }
362+
363+ * olen += ilen ;
364+ }
365+
366+ return ( 0 );
367+ }
368+ #endif /* MBEDTLS_GCM_C */
369+
301370#if defined(MBEDTLS_CIPHER_MODE_CBC )
302371 if ( ctx -> cipher_info -> mode == MBEDTLS_MODE_CBC )
303372 {
@@ -614,7 +683,6 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
614683
615684 if ( MBEDTLS_MODE_CFB == ctx -> cipher_info -> mode ||
616685 MBEDTLS_MODE_CTR == ctx -> cipher_info -> mode ||
617- MBEDTLS_MODE_GCM == ctx -> cipher_info -> mode ||
618686 MBEDTLS_MODE_STREAM == ctx -> cipher_info -> mode )
619687 {
620688 return ( 0 );
@@ -628,6 +696,16 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
628696 return ( 0 );
629697 }
630698
699+ #if defined(MBEDTLS_GCM_C )
700+ if ( MBEDTLS_MODE_GCM == ctx -> cipher_info -> mode )
701+ {
702+ /* cipher block */
703+ * olen = ctx -> unprocessed_len ;
704+ return mbedtls_gcm_update ( (mbedtls_gcm_context * ) ctx -> cipher_ctx ,
705+ ctx -> unprocessed_len , ctx -> unprocessed_data , output );
706+ }
707+ #endif /* MBEDTLS_GCM_C */
708+
631709#if defined(MBEDTLS_CIPHER_MODE_CBC )
632710 if ( MBEDTLS_MODE_CBC == ctx -> cipher_info -> mode )
633711 {
@@ -644,7 +722,7 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
644722 return ( 0 );
645723 }
646724
647- ctx -> add_padding ( ctx -> unprocessed_data , mbedtls_cipher_get_iv_size ( ctx ),
725+ ctx -> add_padding ( ctx -> unprocessed_data , mbedtls_cipher_get_block_size ( ctx ),
648726 ctx -> unprocessed_len );
649727 }
650728 else if ( mbedtls_cipher_get_block_size ( ctx ) != ctx -> unprocessed_len )
@@ -676,10 +754,11 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
676754 * olen = mbedtls_cipher_get_block_size ( ctx );
677755 return ( 0 );
678756 }
679- #else
680- ((void ) output );
681757#endif /* MBEDTLS_CIPHER_MODE_CBC */
682758
759+ #if !defined(MBEDTLS_MODE_CBC ) && !defined(MBEDTLS_MODE_GCM )
760+ ((void ) output );
761+ #endif
683762 return ( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
684763}
685764
0 commit comments