int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( MBEDTLS_ENCRYPT != ctx->operation ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); #endif #if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { /* Don't allow truncated MAC for Poly1305 */ if ( tag_len != 16U ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ); } #endif return( 0 ); }
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { unsigned char check_tag[16]; int ret; if( NULL == ctx || NULL == ctx->cipher_info || MBEDTLS_DECRYPT != ctx->operation ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } #if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { if( tag_len > sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, check_tag, tag_len ) ) ) { return( ret ); } /* Check the tag in "constant-time" */ if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); return( 0 ); } #endif /* MBEDTLS_GCM_C */ #if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { /* Don't allow truncated MAC for Poly1305 */ if ( tag_len != sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); if ( ret != 0 ) { return( ret ); } /* Check the tag in "constant-time" */ if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); return( 0 ); } #endif /* MBEDTLS_CHACHAPOLY_C */ return( 0 ); }
int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( MBEDTLS_ENCRYPT != ctx->operation ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); return( 0 ); }
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { int ret; if( NULL == ctx || NULL == ctx->cipher_info || MBEDTLS_DECRYPT != ctx->operation ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { unsigned char check_tag[16]; size_t i; int diff; if( tag_len > sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, check_tag, tag_len ) ) ) { return( ret ); } /* Check the tag in "constant-time" */ for( diff = 0, i = 0; i < tag_len; i++ ) diff |= tag[i] ^ check_tag[i]; if( diff != 0 ) return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); return( 0 ); } return( 0 ); }
int GCMContext::finish(State & state, mbedtls_gcm_context * context){ Stack * stack = state.stack; if (stack->is<LUA_TNUMBER>(1)){ size_t tagLength = stack->to<int>(1); if ((tagLength >= 4) && (tagLength <= 16)){ unsigned char * tag = new unsigned char[tagLength]; int result = mbedtls_gcm_finish(context, tag, tagLength); if (result == 0){ stack->pushLString(std::string(reinterpret_cast<char*>(tag), tagLength)); delete[] tag; } else{ delete[] tag; stack->push<int>(result); } return 1; } } return 0; }