]> git.cryptolib.org Git - avr-crypto-lib.git/blobdiff - base64/base64_dec.c
bug fixing and support for malloc instead of stack memory (some functions)
[avr-crypto-lib.git] / base64 / base64_dec.c
index 2a6e94141868b8e86a3e94847fe6dd9825572bf3..5e22d566c0f1a864967a3556c4de6e65ec1f4f76 100644 (file)
@@ -17,7 +17,6 @@
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
 /**
  * base64 decoder (RFC3548)
  * Author: Daniel Otte
 
 /*
  #define USE_GCC_EXTENSION
-*/
+ */
 #if 1
 
 #ifdef USE_GCC_EXTENSION
 
 static
-int ascii2bit6(char a){
-       switch(a){
-               case 'A'...'Z':
-                       return a-'A';
-               case 'a'...'z':
-                       return a-'a'+26;
-               case '0'...'9':
-                       return a-'0'+52;
-               case '+':
-               case '-':
-                       return 62;
-               case '/':
-               case '_':
-                       return 63;
-               default:
-                       return -1;
-       }
+int ascii2bit6(char a) {
+    switch(a) {
+        case 'A'...'Z':
+        return a-'A';
+        case 'a'...'z':
+        return a-'a'+26;
+        case '0'...'9':
+        return a-'0'+52;
+        case '+':
+        case '-':
+        return 62;
+        case '/':
+        case '_':
+        return 63;
+        default:
+        return -1;
+    }
 }
 
 #else
 
-static
-uint8_t ascii2bit6(char a){
-       int r;
-       switch(a>>4){
-               case 0x5:
-               case 0x4: 
-                       r=a-'A';
-                       if(r<0 || r>25){
-                               return -1;
-                       } else {
-                               return r;
-                       }
-               case 0x7:
-               case 0x6: 
-                       r=a-'a';
-                       if(r<0 || r>25){
-                               return -1;
-                       } else {
-                               return r+26;
-                       }
-                       break;
-               case 0x3:
-                       if(a>'9')
-                               return -1;
-                       return a-'0'+52;
-               default:
-                       break;  
-       }
-       switch (a){
-               case '+':
-               case '-':
-                       return 62;
-               case '/':
-               case '_':
-                       return 63;
-               default:
-                       return 0xff;
-       }
+static uint8_t ascii2bit6(char a)
+{
+    int r;
+    switch (a >> 4) {
+    case 0x5:
+        case 0x4:
+        r = a - 'A';
+        if (r < 0 || r > 25) {
+            return -1;
+        } else {
+            return r;
+        }
+    case 0x7:
+        case 0x6:
+        r = a - 'a';
+        if (r < 0 || r > 25) {
+            return -1;
+        } else {
+            return r + 26;
+        }
+        break;
+    case 0x3:
+        if (a > '9')
+            return -1;
+        return a - '0' + 52;
+    default:
+        break;
+    }
+    switch (a) {
+    case '+':
+        case '-':
+        return 62;
+    case '/':
+        case '_':
+        return 63;
+    default:
+        return 0xff;
+    }
 }
 
 #endif
 
 #else
 
-static 
-uint8_t ascii2bit6(uint8_t a){
-       if(a>='A' && a<='Z'){
-               return a-'A';
-       } else {
-               if(a>='a' && a<= 'z'){
-                       return a-'a'+26;
-               } else {
-                       if(a>='0' && a<='9'){
-                               return a-'0'+52;
-                       } else {
-                               if(a=='+' || a=='-'){
-                                       return 62;
-                               } else {
-                                       if(a=='/' || a=='_'){
-                                               return 63;
-                                       } else {
-                                               return 0xff;
-                                       }
-                               }
-                       }
-               }
-       }
+static
+uint8_t ascii2bit6(uint8_t a) {
+    if(a>='A' && a<='Z') {
+        return a-'A';
+    } else {
+        if(a>='a' && a<= 'z') {
+            return a-'a'+26;
+        } else {
+            if(a>='0' && a<='9') {
+                return a-'0'+52;
+            } else {
+                if(a=='+' || a=='-') {
+                    return 62;
+                } else {
+                    if(a=='/' || a=='_') {
+                        return 63;
+                    } else {
+                        return 0xff;
+                    }
+                }
+            }
+        }
+    }
 }
 
 #endif
 
-int base64_binlength(char *str, uint8_t strict){
-       int l=0;
-       uint8_t term=0;
-       for(;;){
-               if(*str=='\0')
-                       break;
-               if(*str=='\n' || *str=='\r'){
-                       str++;
-                       continue;
-               }
-               if(*str=='='){
-                       term++;
-                       str++;
-                       if(term==2){
-                               break;
-                       }
-                       continue;
-               }
-               if(term)
-                       return -1;
-               if(ascii2bit6(*str)==-1){
-                       if(strict)
-                               return -1;
-               } else {
-                       l++;
-               }
-               str++;
-       }
-       switch(term){
-               case 0:
-                       if(l%4!=0)
-                               return -1;
-                       return l/4*3;
-               case 1:
-                       if(l%4!=3)
-                               return -1;
-                       return (l+1)/4*3-1;
-               case 2:
-                       if(l%4!=2)
-                               return -1;
-                       return (l+2)/4*3-2;
-               default:
-                       return -1;
-       }
+int base64_binlength(char *str, uint8_t strict)
+{
+    int l = 0;
+    uint8_t term = 0;
+    for (;;) {
+        if (*str == '\0')
+            break;
+        if (*str == '\n' || *str == '\r') {
+            str++;
+            continue;
+        }
+        if (*str == '=') {
+            term++;
+            str++;
+            if (term == 2) {
+                break;
+            }
+            continue;
+        }
+        if (term)
+            return -1;
+        if (ascii2bit6(*str) == -1) {
+            if (strict)
+                return -1;
+        } else {
+            l++;
+        }
+        str++;
+    }
+    switch (term) {
+    case 0:
+        if (l % 4 != 0)
+            return -1;
+        return l / 4 * 3;
+    case 1:
+        if (l % 4 != 3)
+            return -1;
+        return (l + 1) / 4 * 3 - 1;
+    case 2:
+        if (l % 4 != 2)
+            return -1;
+        return (l + 2) / 4 * 3 - 2;
+    default:
+        return -1;
+    }
 }
 
 /*
 |543210543210543210543210|
 |765432107654321076543210|
+ |543210543210543210543210|
+ |765432107654321076543210|
 
       .      .      .     .
 |54321054|32105432|10543210|
 |76543210|76543210|76543210|
+ .      .      .     .
+ |54321054|32105432|10543210|
+ |76543210|76543210|76543210|
 
-*/
+ */
 
-int base64dec(void *dest, const char *b64str, uint8_t strict){
-       uint8_t buffer[4];
-       uint8_t idx=0;
-       uint8_t term=0;
-       for(;;){
+int base64dec(void *dest, const char *b64str, uint8_t strict)
+{
+    uint8_t buffer[4];
+    uint8_t idx = 0;
+    uint8_t term = 0;
+    for (;;) {
 //             cli_putstr_P(PSTR("\r\n  DBG: got 0x"));
 //             cli_hexdump(b64str, 1);
-               buffer[idx]= ascii2bit6(*b64str);
+        buffer[idx] = ascii2bit6(*b64str);
 //             cli_putstr_P(PSTR(" --> 0x"));
 //             cli_hexdump(buffer+idx, 1);
-               
-               if(buffer[idx]==0xFF){
-                       if(*b64str=='='){
-                               term++;
-                               b64str++;
-                               if(term==2)
-                                       goto finalize; /* definitly the end */
-                       }else{
-                               if(*b64str == '\0'){
-                                       goto finalize; /* definitly the end */
-                               }else{
-                                       if(*b64str == '\r' || *b64str == '\n' || !(strict)){
-                                               b64str++; /* charcters that we simply ignore */
-                                       }else{
-                                               return -1;
-                                       }
-                               }
-                       }
-               }else{
-                       if(term)
-                               return -1; /* this happens if we get a '=' in the stream */
-                       idx++;
-                       b64str++;
-               }
-               if(idx==4){
-                       ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-                       ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;
-                       ((uint8_t*)dest)[2] = buffer[2]<<6 | buffer[3];
-                       dest = (uint8_t*)dest +3;
-                       idx=0;
-               }
-       }
-  finalize:    
-       /* the final touch */
-       if(idx==0)
-               return 0;
-       if(term==1){
-               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-               ((uint8_t*)dest)[1] = buffer[1]<<4 | buffer[2]>>2;                      
-               return 0;
-       }
-       if(term==2){
-               ((uint8_t*)dest)[0] = buffer[0]<<2 | buffer[1]>>4;
-               return 0;
-       }
-       return -1;
+
+        if (buffer[idx] == 0xFF) {
+            if (*b64str == '=') {
+                term++;
+                b64str++;
+                if (term == 2)
+                    goto finalize;
+                /* definitly the end */
+            } else {
+                if (*b64str == '\0') {
+                    goto finalize;
+                    /* definitly the end */
+                } else {
+                    if (*b64str == '\r' || *b64str == '\n' || !(strict)) {
+                        b64str++; /* charcters that we simply ignore */
+                    } else {
+                        return -1;
+                    }
+                }
+            }
+        } else {
+            if (term)
+                return -1; /* this happens if we get a '=' in the stream */
+            idx++;
+            b64str++;
+        }
+        if (idx == 4) {
+            ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;
+            ((uint8_t*) dest)[1] = buffer[1] << 4 | buffer[2] >> 2;
+            ((uint8_t*) dest)[2] = buffer[2] << 6 | buffer[3];
+            dest = (uint8_t*) dest + 3;
+            idx = 0;
+        }
+    }
+    finalize:
+    /* the final touch */
+    if (idx == 0)
+        return 0;
+    if (term == 1) {
+        ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;
+        ((uint8_t*) dest)[1] = buffer[1] << 4 | buffer[2] >> 2;
+        return 0;
+    }
+    if (term == 2) {
+        ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;
+        return 0;
+    }
+    return -1;
 }