diff --git a/base64-decode.c b/base64-decode.c
index e1e614de1ef7257765fafaf8ee085679cf55ce25..74ca0afedaafc12db3417272d2809e82c3ad1e52 100644
--- a/base64-decode.c
+++ b/base64-decode.c
@@ -59,6 +59,61 @@ base64_decode_init(struct base64_decode_ctx *ctx)
   ctx->status = BASE64_DECODE_OK;
 }
 
+unsigned
+base64_decode_single(struct base64_decode_ctx *ctx,
+		     uint8_t *dst,
+		     uint8_t src)
+{
+  int data;
+  
+  if (ctx->status == BASE64_DECODE_ERROR)
+    return 0;
+
+  data = decode_table[src];
+
+  switch(data)
+    {
+    default:
+      {
+	unsigned done = 0;
+	
+	assert(data >= 0 && data < 0x40);
+	  
+	if (ctx->status != BASE64_DECODE_OK)
+	  goto invalid;
+	
+	ctx->word = ctx->word << 6 | data;
+	ctx->bits += 6;
+	
+	if (ctx->bits >= 8)
+	  {
+	    ctx->bits -= 8;
+	    dst[done++] = ctx->word >> ctx->bits;
+	  }
+	return done;
+      }
+    case TABLE_INVALID:
+    invalid:
+      ctx->status = BASE64_DECODE_ERROR;
+      return 0;
+
+    case TABLE_END:
+      if (!ctx->bits)
+	goto invalid;
+      if (ctx->word & ( (1<<ctx->bits) - 1))
+	/* We shouldn't have any leftover bits */
+	goto invalid;
+	  
+      ctx->status = BASE64_DECODE_END;
+      ctx->bits -= 2;
+      /* Fall through */
+      
+    case TABLE_SPACE:
+      /* Ignore */
+      return 0;
+    }
+}
+
 unsigned
 base64_decode_update(struct base64_decode_ctx *ctx,
 		     uint8_t *dst,
@@ -72,48 +127,7 @@ base64_decode_update(struct base64_decode_ctx *ctx,
     return 0;
 
   for (i = 0; i<length; i++)
-    {
-      int data = decode_table[src[i]];
-
-      switch(data)
-	{
-	default:
-	  assert(data >= 0 && data < 0x40);
-	  
-	  if (ctx->status != BASE64_DECODE_OK)
-	    goto invalid;
-	  
-	  ctx->word = ctx->word << 6 | data;
-	  ctx->bits += 6;
-
-	  if (ctx->bits >= 8)
-	    {
-	      ctx->bits -= 8;
-	      dst[done++] = ctx->word >> ctx->bits;
-	    }
-	  break;
-
-	case TABLE_INVALID:
-	invalid:
-	  ctx->status = BASE64_DECODE_ERROR;
-	  return done;
-
-	case TABLE_SPACE:
-	  /* Ignore */
-	  break;
-
-	case TABLE_END:
-	  if (!ctx->bits)
-	    goto invalid;
-	  if (ctx->word & ( (1<<ctx->bits) - 1))
-	    /* We shouldn't have any leftover bits */
-	    goto invalid;
-	  
-	  ctx->status = BASE64_DECODE_END;
-	  ctx->bits -= 2;
-	  break;
-	}
-    }
+    done += base64_decode_single(ctx, dst + done, src[i]);
 
   assert(done <= BASE64_DECODE_LENGTH(length));
   
diff --git a/base64.h b/base64.h
index 78b0711a4170fe07deffc27b58e9517a3b9616ef..3084bbff6329a8350feb7b2bdda9128e57b319a8 100644
--- a/base64.h
+++ b/base64.h
@@ -55,7 +55,7 @@ struct base64_encode_ctx
 void
 base64_encode_init(struct base64_encode_ctx *ctx);
 
-/* Encodes a single byte. Returns amoutn of output (always 1 or 2). */
+/* Encodes a single byte. Returns amount of output (always 1 or 2). */
 unsigned
 base64_encode_single(struct base64_encode_ctx *ctx,
 		     uint8_t *dst,
@@ -108,6 +108,13 @@ struct base64_decode_ctx
 void
 base64_decode_init(struct base64_decode_ctx *ctx);
 
+/* Decodes a single byte. Returns amount of output (always 0 or 1).
+ * FIXME: What to return on errors? */
+unsigned
+base64_decode_single(struct base64_decode_ctx *ctx,
+		     uint8_t *dst,
+		     uint8_t src);
+
 /* Returns the number of output characters. DST should point to an
  * area of size at least BASE64_DECODE_LENGTH(length). */
 unsigned