diff --git a/src/ffisyms.cc b/src/ffisyms.cc
index 6a6d8290d53af83637b5d45ac0b229ceaeb8099f..725dddb914adbb39748ffd775e5b3541d3687160 100644
--- a/src/ffisyms.cc
+++ b/src/ffisyms.cc
@@ -47,5 +47,7 @@ void *ffi_symbols[] = {
 	(void *) bsdsocket_local_resolve,
 	(void *) bsdsocket_nonblock,
 	(void *) base64_decode,
+	(void *) base64_encode,
+	(void *) base64_bufsize,
 	(void *) SHA1internal
 };
diff --git a/src/lua/digest.lua b/src/lua/digest.lua
index dd942480c2147b0cff7fe248642bfed856ae824f..3f5653be86145e88d8f376ed21873dc58ee1faef 100644
--- a/src/lua/digest.lua
+++ b/src/lua/digest.lua
@@ -27,6 +27,7 @@ ffi.cdef[[
     extern crc32_func crc32_calc;
 
    /* base64 */
+   int base64_bufsize(int binsize);
    int base64_decode(const char *in_base64, int in_len, char *out_bin, int out_len);
    int base64_encode(const char *in_bin, int in_len, char *out_base64, int out_len);
 ]]
@@ -72,34 +73,25 @@ end
 
 local m = {
     base64_encode = function(bin)
-        if bin == nil then
-            error('Usage: base64.encode(str)')
-        else
-            -- note: need add check size of bin, bin might containe any binary data
-            if type(bin) == 'string' then
-                local blen = string.len(bin)
-                local slen = math.ceil(blen * 4 / 3) + 2
-                local so  = ffi.new('char[?]', slen)
-                local len = ffi.C.base64_encode(bin, blen, so, slen)
-                bin = ffi.string(so, len)
-            else
-                bin = ''
-            end
+        if type(bin) ~= 'string' then
+            error('Usage: digest.base64_encode(string)')
         end
-        return bin
+        local blen = #bin
+        local slen = ffi.C.base64_bufsize(blen)
+        local str  = ffi.new('char[?]', slen)
+        local len = ffi.C.base64_encode(bin, blen, str, slen)
+        return ffi.string(str, len)
     end,
 
-    base64_decode = function(data)
-        if type(data) ~= 'string' then
-            data = ''
-        else
-            local slen = string.len(data)
-            local blen = math.ceil(slen * 3 / 4)
-            local bo  = ffi.new('char[?]', blen)
-            local len = ffi.C.base64_decode(data, slen, bo, blen)
-            data = ffi.string(bo, len)
+    base64_decode = function(str)
+        if type(str) ~= 'string' then
+            error('Usage: digest.base64_decode(string)')
         end
-        return data
+        local slen = #str
+        local blen = math.ceil(slen * 3 / 4)
+        local bin  = ffi.new('char[?]', blen)
+        local len = ffi.C.base64_decode(str, slen, bin, blen)
+        return ffi.string(bin, len)
     end,
 
     crc32 = function(str)
diff --git a/test/box/digest.result b/test/box/digest.result
index 21588a9f96af172f0df0eb89b1489bb0991f6e90..0113ed92b6cd092d4543bde83331d1a09f28dce3 100644
--- a/test/box/digest.result
+++ b/test/box/digest.result
@@ -173,21 +173,39 @@ digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
 ---
 - 11 00 11 00 abcdef ABCDEF 00 11 00 11
 ...
+s = string.rep('a', 54 * 2) -- two lines in base64
+---
+...
+b = digest.base64_encode(s)
+---
+...
+b
+---
+- 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+  YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh
+
+'
+...
+digest.base64_decode(b) == s
+---
+- true
+...
 digest.base64_decode(nil)
 ---
-- 
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
 ...
 digest.base64_encode(nil)
 ---
-- error: 'builtin/digest.lua:76: Usage: base64.encode(str)'
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
 ...
 digest.base64_encode(123)
 ---
-- 
+- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
 ...
 digest.base64_decode(123)
 ---
-- 
+- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
 ...
 digest = nil
 ---
diff --git a/test/box/digest.test.lua b/test/box/digest.test.lua
index f988abc98bdc3946c917f79ba5b620c204a25241..6475bf6b650136b9cd62cc81a0d1b134d9989b7d 100644
--- a/test/box/digest.test.lua
+++ b/test/box/digest.test.lua
@@ -50,6 +50,10 @@ digest.base64_encode('asdfl asdf adfa zxc vzxcvz llll')
 digest.base64_decode('YXNkZmwgYXNkZiBhZGZhIHp4YyB2enhjdnogbGxsbA==')
 digest.base64_encode('11 00 11 00 abcdef ABCDEF 00 11 00 11')
 digest.base64_decode('MTEgMDAgMTEgMDAgYWJjZGVmIEFCQ0RFRiAwMCAxMSAwMCAxMQ==')
+s = string.rep('a', 54 * 2) -- two lines in base64
+b = digest.base64_encode(s)
+b
+digest.base64_decode(b) == s
 digest.base64_decode(nil)
 digest.base64_encode(nil)
 digest.base64_encode(123)
diff --git a/third_party/base64.c b/third_party/base64.c
index e2fb9785c43ce65a76c2077455a1e18a0b4126a1..49a4f2492d28ab85fee030b550cd3c0f84978c38 100644
--- a/third_party/base64.c
+++ b/third_party/base64.c
@@ -35,6 +35,9 @@
 
 /* {{{ encode */
 
+extern inline int
+base64_bufsize(int binsize);
+
 enum base64_encodestep { step_A, step_B, step_C };
 
 struct base64_encodestate {
diff --git a/third_party/base64.h b/third_party/base64.h
index d590820ddb775f816cce7ef9941d47cd8cd70890..a52a5e91f7e767a3694f2efb9a70271279230187 100644
--- a/third_party/base64.h
+++ b/third_party/base64.h
@@ -39,7 +39,7 @@ extern "C" {
 
 #define BASE64_CHARS_PER_LINE 72
 
-static inline int
+inline int
 base64_bufsize(int binsize)
 {
 	int datasize = binsize * 4/3 + 4;