Avoid in-out length in base64
diff --git a/include/mbedtls/base64.h b/include/mbedtls/base64.h
index 86fce79..b731885 100644
--- a/include/mbedtls/base64.h
+++ b/include/mbedtls/base64.h
@@ -37,37 +37,39 @@
  * \brief          Encode a buffer into base64 format
  *
  * \param dst      destination buffer
- * \param dlen     size of the buffer
+ * \param dlen     size of the destination buffer
+ * \param olen     number of bytes written
  * \param src      source buffer
  * \param slen     amount of data to be encoded
  *
  * \return         0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
- *                 *dlen is always updated to reflect the amount
+ *                 *olen is always updated to reflect the amount
  *                 of data that has (or would have) been written.
  *
- * \note           Call this function with *dlen = 0 to obtain the
- *                 required buffer size in *dlen
+ * \note           Call this function with dlen = 0 to obtain the
+ *                 required buffer size in *olen
  */
-int mbedtls_base64_encode( unsigned char *dst, size_t *dlen,
+int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen );
 
 /**
  * \brief          Decode a base64-formatted buffer
  *
  * \param dst      destination buffer (can be NULL for checking size)
- * \param dlen     size of the buffer
+ * \param dlen     size of the destination buffer
+ * \param olen     number of bytes written
  * \param src      source buffer
  * \param slen     amount of data to be decoded
  *
  * \return         0 if successful, MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL, or
  *                 MBEDTLS_ERR_BASE64_INVALID_CHARACTER if the input data is
- *                 not correct. *dlen is always updated to reflect the amount
+ *                 not correct. *olen is always updated to reflect the amount
  *                 of data that has (or would have) been written.
  *
- * \note           Call this function with *dst = NULL or *dlen = 0 to obtain
- *                 the required buffer size in *dlen
+ * \note           Call this function with *dst = NULL or dlen = 0 to obtain
+ *                 the required buffer size in *olen
  */
-int mbedtls_base64_decode( unsigned char *dst, size_t *dlen,
+int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen );
 
 /**
diff --git a/library/base64.c b/library/base64.c
index e0a6f18..3e94548 100644
--- a/library/base64.c
+++ b/library/base64.c
@@ -78,7 +78,7 @@
 /*
  * Encode a buffer into base64 format
  */
-int mbedtls_base64_encode( unsigned char *dst, size_t *dlen,
+int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen )
 {
     size_t i, n;
@@ -87,7 +87,7 @@
 
     if( slen == 0 )
     {
-        *dlen = 0;
+        *olen = 0;
         return( 0 );
     }
 
@@ -100,9 +100,9 @@
         default: break;
     }
 
-    if( *dlen < n + 1 )
+    if( dlen < n + 1 )
     {
-        *dlen = n + 1;
+        *olen = n + 1;
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
@@ -135,7 +135,7 @@
         *p++ = '=';
     }
 
-    *dlen = p - dst;
+    *olen = p - dst;
     *p = 0;
 
     return( 0 );
@@ -144,7 +144,7 @@
 /*
  * Decode a base64-formatted buffer
  */
-int mbedtls_base64_decode( unsigned char *dst, size_t *dlen,
+int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
                    const unsigned char *src, size_t slen )
 {
     size_t i, n;
@@ -195,9 +195,9 @@
     n = ( ( n * 6 ) + 7 ) >> 3;
     n -= j;
 
-    if( dst == NULL || *dlen < n )
+    if( dst == NULL || dlen < n )
     {
-        *dlen = n;
+        *olen = n;
         return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
     }
 
@@ -218,7 +218,7 @@
         }
     }
 
-    *dlen = p - dst;
+    *olen = p - dst;
 
     return( 0 );
 }
@@ -253,10 +253,9 @@
     if( verbose != 0 )
         mbedtls_printf( "  Base64 encoding test: " );
 
-    len = sizeof( buffer );
     src = base64_test_dec;
 
-    if( mbedtls_base64_encode( buffer, &len, src, 64 ) != 0 ||
+    if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
          memcmp( base64_test_enc, buffer, 88 ) != 0 )
     {
         if( verbose != 0 )
@@ -268,10 +267,9 @@
     if( verbose != 0 )
         mbedtls_printf( "passed\n  Base64 decoding test: " );
 
-    len = sizeof( buffer );
     src = base64_test_enc;
 
-    if( mbedtls_base64_decode( buffer, &len, src, 88 ) != 0 ||
+    if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
          memcmp( base64_test_dec, buffer, 64 ) != 0 )
     {
         if( verbose != 0 )
diff --git a/library/pem.c b/library/pem.c
index c1561cb..13fc2df 100644
--- a/library/pem.c
+++ b/library/pem.c
@@ -315,8 +315,7 @@
           ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
     }
 
-    len = 0;
-    ret = mbedtls_base64_decode( NULL, &len, s1, s2 - s1 );
+    ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
 
     if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
         return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
@@ -324,7 +323,7 @@
     if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
         return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
 
-    if( ( ret = mbedtls_base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
+    if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 )
     {
         mbedtls_free( buf );
         return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
@@ -396,9 +395,9 @@
 {
     int ret;
     unsigned char *encode_buf, *c, *p = buf;
-    size_t len = 0, use_len = 0, add_len = 0;
+    size_t len = 0, use_len, add_len = 0;
 
-    mbedtls_base64_encode( NULL, &use_len, der_data, der_len );
+    mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len );
     add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
 
     if( use_len + add_len > buf_len )
@@ -410,7 +409,7 @@
     if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL )
         return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
 
-    if( ( ret = mbedtls_base64_encode( encode_buf, &use_len, der_data,
+    if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data,
                                der_len ) ) != 0 )
     {
         mbedtls_free( encode_buf );
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index df25435..9587b7a 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -720,8 +720,7 @@
         mbedtls_printf( "  > Write username to server: %s", opt.user_name );
         fflush( stdout );
 
-        n = sizeof( base );
-        ret = mbedtls_base64_encode( base, &n, (const unsigned char *) opt.user_name,
+        ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) opt.user_name,
                              strlen( opt.user_name ) );
 
         if( ret != 0 ) {
@@ -741,8 +740,7 @@
         mbedtls_printf( "  > Write password to server: %s", opt.user_pwd );
         fflush( stdout );
 
-        n = sizeof( base );
-        ret = mbedtls_base64_encode( base, &n, (const unsigned char *) opt.user_pwd,
+        ret = mbedtls_base64_encode( base, sizeof( base ), &n, (const unsigned char *) opt.user_pwd,
                              strlen( opt.user_pwd ) );
 
         if( ret != 0 ) {
diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c
index c9b511d..d43d446 100644
--- a/programs/util/pem2der.c
+++ b/programs/util/pem2der.c
@@ -96,14 +96,14 @@
     if( s2 <= s1 || s2 > end )
         return( -1 );
 
-    ret = mbedtls_base64_decode( NULL, &len, (const unsigned char *) s1, s2 - s1 );
+    ret = mbedtls_base64_decode( NULL, 0, &len, (const unsigned char *) s1, s2 - s1 );
     if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
         return( ret );
 
     if( len > *olen )
         return( -1 );
 
-    if( ( ret = mbedtls_base64_decode( output, &len, (const unsigned char *) s1,
+    if( ( ret = mbedtls_base64_decode( output, len, &len, (const unsigned char *) s1,
                                s2 - s1 ) ) != 0 )
     {
         return( ret );
diff --git a/tests/suites/test_suite_base64.function b/tests/suites/test_suite_base64.function
index 53f38bf..ab6d88c 100644
--- a/tests/suites/test_suite_base64.function
+++ b/tests/suites/test_suite_base64.function
@@ -13,13 +13,13 @@
 {
     unsigned char src_str[1000];
     unsigned char dst_str[1000];
-    size_t len = dst_buf_size;
+    size_t len;
 
     memset(src_str, 0x00, 1000);
     memset(dst_str, 0x00, 1000);
 
     strncpy( (char *) src_str, src_string, sizeof(src_str) - 1 );
-    TEST_ASSERT( mbedtls_base64_encode( dst_str, &len, src_str, strlen( (char *) src_str ) ) == result );
+    TEST_ASSERT( mbedtls_base64_encode( dst_str, dst_buf_size, &len, src_str, strlen( (char *) src_str ) ) == result );
     if( result == 0 )
     {
         TEST_ASSERT( strcmp( (char *) dst_str, dst_string ) == 0 );
@@ -32,14 +32,14 @@
 {
     unsigned char src_str[1000];
     unsigned char dst_str[1000];
-    size_t len = 1000;
+    size_t len;
     int res;
 
     memset(src_str, 0x00, 1000);
     memset(dst_str, 0x00, 1000);
 
     strncpy( (char *) src_str, src_string, sizeof(src_str) - 1 );
-    res = mbedtls_base64_decode( dst_str, &len, src_str, strlen( (char *) src_str ) );
+    res = mbedtls_base64_decode( dst_str, sizeof( dst_str ), &len, src_str, strlen( (char *) src_str ) );
     TEST_ASSERT( res == result );
     if( result == 0 )
     {
@@ -53,12 +53,12 @@
                         int result )
 {
     unsigned char *src = NULL, *res = NULL;
-    size_t len = dst_buf_size, src_len;
+    size_t len, src_len;
 
     src = unhexify_alloc( src_hex, &src_len );
     res = zero_alloc( dst_buf_size );
 
-    TEST_ASSERT( mbedtls_base64_encode( res, &len, src, src_len ) == result );
+    TEST_ASSERT( mbedtls_base64_encode( res, dst_buf_size, &len, src, src_len ) == result );
     if( result == 0 )
     {
         TEST_ASSERT( len == strlen( dst ) );
@@ -76,12 +76,12 @@
                         int result )
 {
     unsigned char *dst = NULL, *res = NULL;
-    size_t len = dst_buf_size, dst_len;
+    size_t len, dst_len;
 
     dst = unhexify_alloc( dst_hex, &dst_len );
     res = zero_alloc( dst_buf_size );
 
-    TEST_ASSERT( mbedtls_base64_decode( res, &len, (unsigned char *) src,
+    TEST_ASSERT( mbedtls_base64_decode( res, dst_buf_size, &len, (unsigned char *) src,
                                 strlen( src ) ) == result );
     if( result == 0 )
     {
@@ -104,8 +104,7 @@
 
     src = unhexify_alloc( src_hex, &src_len );
 
-    len = sizeof( dst );
-    TEST_ASSERT( mbedtls_base64_decode( dst, &len, src, src_len ) == result );
+    TEST_ASSERT( mbedtls_base64_decode( dst, sizeof( dst ), &len, src, src_len ) == result );
     if( result == 0 )
     {
         TEST_ASSERT( len == strlen( dst_ref ) );